I write a program that validate ISBN number. Everything works fine but It can not open the file which contain ISBN numbers. Can anyone show me why?
Code:
#include <iostream>
#include <fstream>
#include <cctype>
#include <string>
using namespace std;
// Constant declarations
const char NWLN = '\n'; // Defines newline in stream
// Function declarations
void instruction(); // Displays instructions
void userinput(char&); // Gets user input
void fileinput(char&); // Gets file input
void test(string); // Tests ISBN numbers
void convert(char, int&); // Converts character numbers to int numbers
// Start of main
int main()
{
int choice; // User choice value
char check; // Main loop test flag
// Start of main loop
do { // while check is equal to m
instruction(); // Give user instructions
// Get user input
cout << "Choice: ";
cin >> choice;
cout << " " << endl;
// User choice decision switch statment
switch(choice)
{
case 1: // Manual input
userinput(check);
break;
case 2: // File input
fileinput(check);
break;
case 3: // All done!
cout << "Quit" << endl; // Check flag set to end loop
check = 'q';
break;
default:
cerr << "Invalid choice " << choice << endl
<< "please try again. " << endl << endl;
}
// End switch
} while (check == 'm');
// End main loop
system("pause");
return 0;
}
// End main
// Instruction subprogram
void instruction()
{
cout << "Validate ISBN" << endl << endl << endl;
cout << "| Enter 1 to enter ISBN number." << endl
<< "| Enter 2 to enter a text file of isbn numbers." << endl
<< "| Enter 3 to quit." << endl << endl;
}
// End subprogram
// User input subprogram: Gets user isbn number
void userinput(char& check)
{
string isbn; // Isbn number
cout << "Enter an isbn: ";
cin.ignore(80, '\n');
getline(cin, isbn);
if (isbn.at(isbn.length() - 1) == '\n')
isbn.erase(isbn.length() - 1, 1);
cout << " " << endl;
// Test isbn number main loop
while (isbn.at(0) != 'M' && isbn.at(0) != 'm')
{
test(isbn);
cout << "Enter an isbn or 'M' to return to main menu:";
getline(cin, isbn);
if (isbn.at(isbn.length() - 1) == '\n')
isbn.erase(isbn.length() - 1, 1);
cout << " " << endl;
}
// End loop
check = 'm';
}
// End subprogram
// File input subprogram: Gets file with isbn numbers
void fileinput(char& check)
{
string file;
string isbn; // Isbn number
int num; // Number of isbn's in file
int linecount; // Line count flag to compare with sum
ifstream ins; // Define input
linecount = 0;
num = 0;
cout << "Enter filename with isbn numbers: ";
cin >> file;
// Open file
ins.open(file.c_str());
// File open error
if (ins.fail())
{
cerr << "Error - Can't open file " << file << endl;
check = 'm';
}
else
ins >> num;
ins.ignore(100, NWLN);
getline(ins, isbn);
if (isbn.at(isbn.length() - 1) == '\n')
isbn.erase(isbn.length() - 1, 1);
// Test isbn number main loop
while (!ins.eof() && num != linecount)
{
linecount++;
cout << isbn << endl;
test(isbn);
getline(ins, isbn);
if (isbn.at(isbn.length() - 1) == '\n')
isbn.erase(isbn.length() - 1, 1);
}
// Close input file
ins.close();
}
cout << " " << endl;
check = 'm';
}
// End subprogram
// Test subprogram: Tests isbn number
void test(string isbn)
{
int charcount; // Count of character digits
int dashstart; // Test variable for dash at beginning or end of number
int counter; // Counts characters in string and used in testing
int value; // Value of isbn formula and final value equals remainder of formula
int lettercheck; // Test count variable for letter in isbn
int dashcount; // Test count variable for dashes in isbn
int doubledash; // Test count variable for double dashes in isbn
int spacecount; // Test count variable for spaces in isbn
int digit; // Int value of character digit
int length; // Isbn length
int i;
char checkdigit; // Checkdigit number
char lastchar; // Record last character variable
spacecount = 0;
lettercheck = 0;
value = 0;
counter = 1;
dashstart = 0;
charcount = 0;
dashcount = 0;
doubledash = 0;
length = isbn.length();
// Test isbn for loop
for(int i=0; i < length - 1; i++) // for each character
{
// Check for dash in beginning or end of number
if (isbn.at(0) == '-' || isbn.at(length - 1) == '-')
{
dashstart = 1;
counter++;
}
// Calculate value if isbn has right amount of numbers
if ((isdigit(isbn.at(i))) &&(charcount < 9) &&(lettercheck == 0) && isbn.at(i) != '-' && isbn.at(i) != ' ')
{
checkdigit = isbn.at(i);
convert(checkdigit, digit);
value = value + (digit * (counter));
counter++;
charcount++;
}
// If isbn has a dash, adds 1 to dashcount
if (isbn.at(i) == '-' && dashstart != 1)
{
dashcount++;
// Check for double dash
if (lastchar == '-')
doubledash++;
else
;
}
// Check for letter
if (isbn.at(i) != '-' && !isdigit(isbn.at(i)) && isbn.at(i) != ' ' && (isbn.at(length - 1) != 'x' || isbn.at(length - 1) != 'X'))
{
lettercheck = 1;
}
// Check for spaces
if (isbn.at(i) == ' ')
{
spacecount++;
}
// Set previous character variable to last character tested
lastchar = isbn.at(i);
} // end for each character
if(dashstart != 1)
{
// Calculate remainder of forumla
value = value % 11;
cout << "ISBN: " << isbn << endl << endl;
cout << "calculated checksum == " << value << endl << endl;
if (length == 13 && lettercheck == 0 && charcount == 9 && dashstart == 0)
{
charcount += 1;
checkdigit = isbn.at(12);
}
else if (length == 10 && lettercheck == 0 && charcount == 9 && dashstart == 0)
{
charcount += 1;
checkdigit = isbn.at(9);
}
else if (dashstart == 1 && charcount == 9 && (i > 9 && i < 12))
{
checkdigit = isbn.at(length -1);
}
else if (dashstart == 1 && charcount == 9 && i > 12)
{
checkdigit = isbn.at(length -1);
}
else
{
cout << "Invalid Isbn" << endl;
}
// Convert last character digit in isbn to int digit to compare to value
convert(checkdigit, digit);
}
// Condition
if (charcount < 10)
cout << " (Not enough digits)" << endl;
if (charcount > 10)
cout << " (To many digits)" << endl;
if (dashcount > 4)
cout << " (Too many dashes)" << endl;
if ((dashcount < 3 && dashcount > 0) && length > 10)
cout << " (Not enough dashes)" << endl;
if (value != digit)
cout << " (Wrong check sum)" << endl;
if (dashstart == 1)
cout << " (Beginning or ending dash)" << endl;
if (doubledash > 0)
cout << " (Sequential dashes)" << endl;
if (spacecount > 4)
cout << " (Too many spaces)" << endl;
else
;
cout << " " << endl;
system("pause");
}
// Converts character digits to int digits
void convert(char checkdigit, int& digit)
{
if (checkdigit == 'x' || checkdigit == 'X')
digit = 10;
else
digit = int(checkdigit) - int('0');
}