// filename = isbn.cpp
// Kyle Burmark
// Prof. Gelotte
// 02/12/02
// Program 4 - Validate ISBN numbers program
// Description: This program asks the user whether he wants to validate
//				ISBN numbers from his own input or from a file of isbn numbers

// Start program

// Header files

#include <iostream>				// In/Out, standard
#include <fstream>				// File input/output
#include <cctype>				// Character testing
#include <string>				// 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 << "Goodbye" << endl;	// Check flag set to end loop
			check = 'q';
			break;
		default: 
			cerr << "Invalid choice - " << choice << endl
				<< "enter again please. " << endl << endl;
		}
		
		// End switch
		
	} while (check == 'm');
	
	// End main loop
	
	system("pause");
	return 0;
}

// End main

// Instruction subprogram

void instruction()
{
	cout << "***** Isbn Number Validator *****" << endl << endl << endl;
	
	cout << "| Enter -1- to validate one or more isbn number by typing them in." << endl
		 << "| Enter -2- to validate 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: "; 

	// !!! error, if i use the getline function instead of just cin
	// like getline(cin, isbn) or getline(cin, isbn, '\n'),
	// it wont take isbn numbers and gives 
	// me an error in the program and according to the book
	// it should work, because i wanted to use getline here to get an
	// isbn number with spaces and it won't let me, so i just used cin. !!!!!
	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')
	{
		system("cls");
		test(isbn);
		system("cls");
		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
	
	system("cls");
	check = 'm';
}

// End subprogram

// File input subprogram: Gets file with isbn numbers

void fileinput(char& check)
{
	string file;				// User's Isbn 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 test
	
	if  (ins.fail())
	{
		cerr << "Error - Can't open file [ " << file << " ] for input" << endl;
		check = 'm';
	}
	
	// End test
	
	// Good open of file
	
	else
	{	
		
		ins >> num;
		ins.ignore(100, NWLN);
		getline(ins, isbn);
		
		// Test isbn number main loop
		
		while (!ins.eof() && num != linecount)
		{	
			system("cls");
			linecount++;
			cout << isbn << endl;
			test(isbn);
			system("cls");
			getline(ins, isbn);
		}
		
		// Close input file
		
		ins.close();
		system("cls");
	}
	
	
	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
	char number;					// Character number
	char prevchar;					// 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) != ' ')
		{
			number = isbn.at(i);
			convert(number, 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 (prevchar == '-')
				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
		
		prevchar = isbn.at(i);

	}       // end for each character
	
	// End loop
	
	
	// If there isn't a dash at beginning or end of number convert
	
	if(dashstart != 1)
	{
		
		// Calculate remainder of forumla
		
		value = value % 11;
		
		// reminder value statements

		cout << "ISBN: " << isbn << endl << endl;
		cout << "calculated checksum == " << value << endl << endl;
	

		if (length == 13 && lettercheck == 0 && charcount == 9 && dashstart == 0)
		{
			charcount += 1;
			number = isbn.at(12);
		}
		else if (length == 10 && lettercheck == 0 && charcount == 9 && dashstart == 0)
		{
			charcount += 1;
			number = isbn.at(9);
		}
		else if (dashstart == 1 && charcount == 9 && (i > 9 && i < 12))
		{
			number = isbn.at(length -1);
		}
		else if (dashstart == 1 && charcount == 9 && i > 12)
		{
			number = isbn.at(length -1);
		}
		else
		{
			cout << "Invalid Isbn - will not calculate checksum, return 1" << endl;
			number = '1';
		}
		// Convert last character digit in isbn to int digit to compare to value
		
		convert(number, digit);
	
	}
	// Answer output statements based on data
	
	if (charcount < 10)
		cout << " (Not enough digits)" << endl;
	if (charcount > 10)
		cout << " (To many digits)" << endl;
	if (charcount  <  10 && lettercheck == 1)
		cout << " (Can't have any character except for 'X' at end unless 10 is the remainder)" << 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;
	if ((spacecount < 3 && spacecount > 0) && length > 10)
		cout << " (Not enough spaces)" << endl;
	if ((spacecount == 0 || spacecount == 3) && (dashcount == 3 || dashcount == 0) && (charcount == 10) && (counter == 10) && (digit == value))
		cout << " (Good number and checksum)" << endl;
	else
		;
	
	cout << " " << endl;
	system("pause");

}   // end test function

// End subprogram

// Convert subprogram: Converts character digits to int digits

void convert(char number, int& digit)
{
	if (number == 'x' || number == 'X')
		digit = 10;
	else
		digit = int(number) - int('0');
}

// End subprogram

// End program

the program still not compile ....cn you help me

You have to pay close attention to the compiler's error messages. Look at the first error message, the compiler will tell you which line the error is on. The list of errors may be different from compiler-to-compiler, so you need to tell us what compiler you are using and post the list of error messages.

Example: I compiled with VC++ 2008 Express. The very first error message is on line 320 else if (dashstart == 1 && charcount == 9 && (i > 9 && i < 12)) and the error message is that the variable i is undefined. To correct that you have to find out where i is declared and correct it to declare it globally to the whole function. If you go to line 233 you will see that variable i is declared in the for loop for(int i=0; i < length - 1; i++) . When declared like that, the variable is only in scope while the loop is executing. You need to declare i up above that loop so that it can be used and referenced by the whole function.

Fixing that error makes the entire program compile without further erorrs.

int i = 0; 
	for(i=0; i < length - 1; i++)     // for each character
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.