// CS 210 EDDIE CHEN
// THIS IS PROGRAM 4 (ISBN-Check), a program that verifies ISBN.

#include <iostream>
#include <fstream>                                                                            // REQUIRED FOR FILE STREAMS
#include <cstdlib>                                                                            // FOR DEFINITION OF EXIT_FAILURE
#include <cctype>
#include <string>
using namespace std;

// ASSOCIATE STREAMS WITH EXTERNAL FILE NAMES
#define inFile "isbntest.txt"                                                                // LINKED ISBN FILE (LIST) SOURCE

// FUNCTIONS USED
void menuPrompt ();                                                                            // MAIN MENU USER INSTRUCTION
void userVal ();                                                                            // MANUAL INPUT VALIDATION
int readFile ();                                                                            // LINKED FILE VALIDATION
bool isbnCheckForUser (string isbn);                                                        // ISBN VALIDATION FUNCTION FOR USER INPUT
bool isbnCheckForFile (string isbn);                                                        // ISBN VALIDATION FUNCTION FOR FILE INPUT

int main ()
{
    char choice;                                                                        // INPUT-MAIN MENU CHOICE
    string isbn;

        do
        {
            menuPrompt ();
            cin >> choice;
            switch (choice)
            {
            case '1':
                    userVal ();
                    break;
            case '2':
                    readFile ();
                    break;
            case '3':
                    cout << "Thank you for using ISBN-Check. Have a nice day!" << endl;
                    break;
            default:
                    cerr << "Oops! Incorrect selection. Please try again." << endl;
            }            
        }
        while (choice != '3');
    
    system ("pause");

    return 0;
}

void menuPrompt ()
{
    cout << "Welcome to ISBN-Check." << endl;
    cout << "This program will verify the format of your ISBN(s)." << endl;
    cout << "To manually input the ISBN(s), enter 1." << endl;
    cout << "To verify the ISBN(s) from the linked .txt file, etner 2." << endl;
    cout << "When you're done, enter 3 to exit the program." << endl;
}

void userVal ()
{
    char subchoice;                                                                            // INPUT- SUB MENU CHOICE
    string isbn;                                                                            // INPUT- ISBN STRING
    do
    {
    cout << "Enter an ISBN:";
    cin >> isbn;
    isbnCheckForUser (isbn);
    if (isbnCheckForUser (isbn) == true)
        cout << "This is a valid ISBN." << endl;
    else
        cout << "This is NOT a valid ISBN." << endl;
    cout << endl;
    cout << "To go back to the main menu, enter 1." << endl;
    cout << "To continue manually inputting ISBN(s), enter any digit besides 1." << endl;
    cin >> subchoice;
    }
    while (subchoice != '1');
    
}

int readFile ()
{
    ifstream fin;
    string isbn;
    fin.open (inFile);
    if (fin.fail ())
    {
        cerr << " ERROR: Cannot open " << inFile << " for input. " << endl;
        return EXIT_FAILURE;                                                                // FAILURE RETURN
    }
    fin >> isbn;
    isbnCheckForFile (isbn);
    if (isbnCheckForFile (isbn) == true)
        cout << "This is a valid ISBN." << endl;
    else
        cout << "This is NOT a valid ISBN." << endl;
        
}

bool isbnCheckForUser (string isbn)
{
    int isbn0;
    int isbn1;
    int isbn2;
    int isbn3;
    int isbn4;
    int isbn5;
    int isbn6;
    int isbn7;
    int isbn8;
    int isbn9;
    int sum;
    int modulo;
    
    if (isbn.at(0) == '-' || isbn.at(isbn.length()-1) == '-')
        cout << "This is NOT a valid ISBN." << endl;
        
        isbn.find('-');                                
        isbn.erase('-');
        isbn.at(0) = isbn0;
        isbn.at(1) = isbn1;
        isbn.at(2) = isbn2;
        isbn.at(3) = isbn3;
        isbn.at(4) = isbn4;
        isbn.at(5) = isbn5;
        isbn.at(6) = isbn6;
        isbn.at(7) = isbn7;
        isbn.at(8) = isbn8;
        isbn.at(9) = isbn9;
            
    if (isbn.at(isbn.length()-1) == 'x' || isbn.at(isbn.length()-1) == 'X')
        isbn9 = 10;
        
    sum= isbn0 * 1 + isbn1 * 2 + isbn2 * 3 + isbn3 * 4 + isbn4 * 5 + isbn5 * 6 + isbn6 * 7 + isbn7 * 8 + isbn8 * 9;
    modulo = sum / 11;
    
    if (modulo = 10 && isbn.at(isbn.length()-1) == 'x' || isbn.at(isbn.length()-1) == 'X')
        cout << "This is a valid ISBN." << endl;
    
    else if (modulo = 10 && isbn.at(isbn.length()-1) != 'x' || isbn.at(isbn.length()-1) != 'X')
        cout << "This is NOT a valid ISBN." << endl;
            
    else if (modulo != isbn9)
        cout << "This is Not a valid ISBN." << endl;
            
    else
        cout << "This is a valid ISBN." << endl;
}

bool isbnCheckForFile (string isbn)
{
    ifstream fin;
    int num_of_isbn;
    int count;
    int isbn0;
    int isbn1;
    int isbn2;
    int isbn3;
    int isbn4;
    int isbn5;
    int isbn6;
    int isbn7;
    int isbn8;
    int isbn9;
    int sum;
    int modulo;

    getline(istream& fin, string& num_of_isbn, char '\n');
    fin.ignore( 80, '\n');
    while (!fin.eof())
        {
            for (count=0; count < num_of_isbn; count++)
                {
                    getline (fin, isbn);
                    if (isbn.at(0) == '-' || isbn.at(isbn.length()-1) == '-')
                    cout << "This is NOT a valid ISBN." << endl;
                    isbn.find('-');                                //HOW DO I COUNT THE NUMBER OF DASHES?
                    isbn.erase('-');
                    isbn.at(0) = isbn0;
                    isbn.at(1) = isbn1;
                    isbn.at(2) = isbn2;
                    isbn.at(3) = isbn3;
                    isbn.at(4) = isbn4;
                    isbn.at(5) = isbn5;
                    isbn.at(6) = isbn6;
                    isbn.at(7) = isbn7;
                    isbn.at(8) = isbn8;
                    isbn.at(9) = isbn9;
                    if (isbn.at(isbn.length()-1) == 'x' || isbn.at(isbn.length()-1) == 'X')
                    isbn9 = 10;
                    sum= isbn0 * 1 + isbn1 * 2 + isbn2 * 3 + isbn3 * 4 + isbn4 * 5 + isbn5 * 6 + isbn6 * 7 + isbn7 * 8 + isbn8 * 9;
                    modulo = sum / 11;
                    if (modulo = 10 && isbn.at(isbn.length()-1) == 'x' || isbn.at(isbn.length()-1) == 'X')
                    cout << "This is a valid ISBN." << endl;
                    else if (modulo = 10 && isbn.at(isbn.length()-1) != 'x' || isbn.at(isbn.length()-1) != 'X')
                    cout << "This is NOT a valid ISBN." << endl;
                    else if (modulo != isbn9)
                    cout << "This is Not a valid ISBN." << endl;
                    else
                    cout << "This is a valid ISBN." << endl;
                }
        }
}

I have the problem with getline in line 170. Please help me

Dani AI

Generated

Short summary and immediate fixes (why getline at line 170 fails)

  • The getline line in your code looks like a declaration instead of a call and the input stream is being used before it is verified-open. As pointed out, make sure the ifstream is opened successfully before reading and call getline correctly.
  • There are also several logic and type errors in the ISBN routine that will either crash (out-of-range accesses) or always produce the wrong result: assigning characters to ints backwards, using division instead of remainder, using = instead of ==, and using the wrong weight scheme for ISBN-10.

Practical, minimal changes to get a correct, robust ISBN-10 check

  • Open the file and check the stream before reading.
  • Strip hyphens/whitespace from the input string and verify you have exactly 10 characters.
  • Convert characters to numeric values (last char may be X meaning 10).
  • Use weights 10..1 and test (sum % 11) == 0 for validity.
  • Always check string length before using at() or operator[] to avoid exceptions.

Example validator and read loop (adapt and drop into your program)

#include <fstream>
#include <iostream>
#include <string>
#include <cctype>
#include <algorithm>

bool isValidISBN10(const std::string &raw) {
    std::string s;
    for (char c : raw) if (!std::isspace((unsigned char)c) && c != '-') s.push_back(c);
    if (s.size() != 10) return false;
    int sum = 0;
    for (int i = 0; i < 10; ++i) {
        int v;
        if (i == 9 && (s[i]=='X' || s[i]=='x')) v = 10;
        else if (std::isdigit((unsigned char)s[i])) v = s[i] - '0';
        else return false;
        sum += (10 - i) * v;
    }
    return (sum % 11) == 0;
}

void processFile(const std::string &path) {
    std::ifstream in(path);
    if (!in) { std::cerr << "Cannot open file\n"; return; }
    std::string line;
    while (std::getline(in, line)) {
        if (line.empty()) continue;
        std::cout << (isValidISBN10(line) ? "This is a valid ISBN." : "This is NOT a valid ISBN.") << '\n';
    }
}

Notes and troubleshooting

  • If your input file starts with a count, read that count with the extraction operator into an int, then use getline for the following lines.
  • Follow ’s direction to use indexing/arrays (or the string indexing above) rather than many separate variables like isbn0..isbn9.
  • Fix operator mistakes (== vs =) and use % for modulus. These changes address the runtime crash and correctness issues while keeping your program structure.

Recommended Answers

All 8 Replies

>> getline(istream& fin, string& num_of_isbn, char '\n');
That is a function prototype, not a function call. As written, it will do nothing. If you want to actually call getline() then you need to change it to this: getline(fin, num_of_isgn); -- Not the '\n' parameter (last parameter) is not needed because that is the default.

I changed it ,but it still not run though, thank you

>>isbn1, isbn2, ...
why not use isbn[10]?
And what are the contents of the infile?

I haven't learn the array yet, that's why...

help please

The ifstream fin was never opened. You have to call fin.open("<the filename here>"); before line 170

fin.open(inFile);
is this what you mean???

fin.open(inFile);
is this what you mean???

Maybe -- depends on what inFile is defined to be. If it's a std::string object then fin.open(inFile.c_str());

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.