# Đề tài: chương trình kiểm tra ISBN

#### Hybrid View

1. Awaiting Email Confirmation
Ngày gia nhập
09 2008
Bài viết
16

## chương trình kiểm tra ISBN

CS 210 - Program #4

An ISBN (International Standard Book Number) identifies a unique publication. An ISBN is ten digits. The first nine digits must be decimal digits (0...9). The tenth may a decimal digit or the letter X, according to the checksum, discussed below. Three single dashes may be between any of the characters, but an ISBN must not begin or end with a dash.

Some example ISBNs:

0-201-88337-6
0-13-117334-0
0821211315 (no dashes ok)
1-57231-866-X

The last character of an ISBN number is a checksum. The checksum is the determined by the first 9 digits; it is computed by taking modulo 11 (the remainder after dividing by 11) of the sum of each digit multiplied by its position in the ISBN. The letter X corresponds to a value of 10.

Here are two ISBNs and the calculations that show how the check sum is determined:

0-201-88337-6 -> (0*1 + 2*2 + 0*3 + 1*4 + 8*5 + 8*6 + 3*7 + 3*8 + 7*9) mod 11 = 6
1-57231-866-X -> (1*1 + 5*2 + 7*3 + 2*4 + 3*5 + 1*6 + 8*7 + 6*8 + 6*9) mod 11 = 10 (X)

www.isbn.org
www.amazon.com Try a book search by ISBN

Some invalid ISBNs:

0-201-88337-63 (too many digits)
0-201-88-337-6 (too many dashes)
0-201883376 (not enough dashes)
0-201-88337-3 (wrong check sum)
-013-117334-0 (beginning or ending dash)
157231--866-X (sequential dashes)
013-1134-0 (too few digits)

Code:
```// filename isbn.cpp

// 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

#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");
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```

tình hình là chương trình vẫn chưa complie ,mong anh em giúp mình cho nó cha.y dùm, email cho pro Huy Nguyen nhung weekend mớii đươc nhưng mình cần nó gấp lấm

2. - Tui giúp cậu lần này thôi đó, code cậu viết fragile quá, không bao giờ handle quá nhiều tasks trong 1 hàm.
- Cậu đang học Uni nào vậy ? Bài này trong cuốn Starting Out C++ phải không, tui thấy quen lắm nhưng không chắc vì sách đó tui bán lại mùa trước rùi.
- Tui làm đơn giản nhất rùi đó, nếu dùng full STL và function object code sẽ more elegant. À con trỏ hàm cũng ok . Trường hợp space thì cậu tự mà thêm vào nhé !
C++ Code:
1. // filename isbn.cpp
2. #include <iostream>             // In/Out, standard
3. #include <fstream>              // File input/output
4. #include <cctype>               // Character testing
5. #include <string>               // String
6.
7. using namespace std;
8.
9. const int MAX_ERRORS          = 9;
10. const int MAX_DASHES          = 3;
11. const int MAX_DIGITS          = 10;
12.
13. enum ErrorType
14. {
15.     BEGIN_OR_END_BY_DASH,     // 1
16.     WRONG_END_DIGIT,          // 2
17.     SEQUENTIAL_DASHES,        // 3
19.     NOT_ENOUGH_DIGITS,        // 5
20.     TOO_MANY_DIGITS,          // 6
21.     NOT_ENOUGH_DASHES,        // 7
22.     TOO_MANY_DASHES,          // 8
23.     WRONG_CHECK_SUM,          // 9
24.     OK_BUT_NOT_WELL_FORM,     // 10
25.     VALID_AND_WELL_FORM       // 11
26. };
27.
28. enum UserOption
29. {
30.     MANUAL_INPUT,
31.     FILE_INPUT,
32.     QUIT,
33.     INVALID_CHOICE
34. };
35.
36.
37. bool       open_input_file( const string& file_name );
38. UserOption get_user_choice();
39. void       print_instruction();
40. string     read_isbn_number( istream& in );
41. bool       open_input_file( ifstream& inf );
42. bool       is_begin_end_dash( const string& isbn );
43. bool       is_last_digit_invalid( const string& isbn );
44. int        count_dashes( const string& isbn );
45. int        count_digits( const string& isbn );
46. bool       is_sequential_dashes( const string& isbn );
47. bool       is_dashes_at_bad_position( const string& isbn );
48. int        get_check_sum( const string& isbn );
49. void       test_isbn( const string& isbn );
50. void       print_error_type_messages( ErrorType er );
51. int        convert_single_char_to_int( char number );
52. bool       continue_or_quit( const char* mess );
53.
54. int main()
55. {
56.     int        choice;                  // User choice value
57.     UserOption usop;
58.     string     isbn_number;
59.     ifstream   inf;
60.     char       retest;
61.
62.     do {
63.         print_instruction();
64.         usop = get_user_choice();
65.
66.         cin.ignore( 80, '\n' );
67.
68.         switch( usop )
69.         {
70.             case MANUAL_INPUT :
71.             {
72.                 cout << "Enter an isbn : ";
73.                 isbn_number = read_isbn_number( cin );
74.                 break;
75.             }
76.             case FILE_INPUT :
77.             {
78.                 if( open_input_file( inf ) )
79.                     isbn_number = read_isbn_number( inf );
80.                 else
81.                     cout << endl;
82.                 break;
83.             }
84.             case QUIT :
85.             {
86.                 cout << "\n... About to Exit " << endl;
87.                 break;
88.             }
89.             default :
90.             {
91.                 cerr << "\n... Invalid choice " << choice << endl;
92.                 break;
93.             }
94.         }
95.
96.         if( !isbn_number.empty() )
97.         {
98.             test_isbn( isbn_number );
99.         }
100.
101.         cout << "\n Hit the enter key to continue....";
102.         cin.ignore( 80, '\n' );
103.
104.         if( usop == FILE_INPUT )
105.             inf.clear();
106.
107.     } while( continue_or_quit( "\n Continue ( Y/n or N/n ) ?" ) );
108.
109.     return 0;
110. }
111.
112. void print_instruction()
113. {
114.     cout << "***** Isbn Number Validator *****" << endl << endl << endl;
115.     cout << "| Enter -1- to validate one or more isbn number by typing them in." << endl
116.          << "| Enter -2- to validate a text file of isbn numbers." << endl
117.          << "| Enter -3- to quit." << endl << endl;
118. }
119.
120. UserOption get_user_choice()
121. {
122.     int        choice;
123.     UserOption usop;
124.
125.     cout << "Choice: ";
126.     cin >> choice;
127.     cout << " " << endl;
128.
129.     switch( choice )
130.     {
131.     case 1 :
132.             usop = MANUAL_INPUT;
133.             break;
134.     case 2 :
135.             usop = FILE_INPUT;
136.             break;
137.     case 3 :
138.             usop = QUIT;
139.             break;
140.     default :
141.             usop = INVALID_CHOICE;
142.             break;
143.     }
144.     return usop;
145. }
146.
147.
148. string read_isbn_number( istream& in )
149. {
150.     string isbn_number;
151.     getline( in, isbn_number );
152.     return isbn_number;
153. }
154.
155. bool open_input_file( ifstream& inf )
156. {
157.     string   file_name;
158.     cout << "Enter input file : \n";
159.     cin >> file_name;
160.
161.     inf.open( file_name.c_str() );
162.     if ( inf.fail() )
163.     {
164.         cerr << "Error - Can't open file [ " << file_name << " ] for input" << endl;
165.         return false;
166.     }
167.     else
168.     {
169.         cout << "Success - Open file [ " << file_name << " ] for input. " << endl;
170.         return true;
171.     }
172. }
173.
174. bool is_begin_end_dash( const string& isbn )
175. {
176.     if( isbn.at( 0 ) == '-' || isbn.at( isbn.length() - 1 ) == '-' )
177.         return true;
178.     return false;
179. }
180.
181. bool is_last_digit_invalid( const string& isbn )
182. {
183.     char last_char = isbn.at( isbn.length() - 1 );
184.     if( last_char != 'x' && last_char != 'X' && !isdigit( last_char ) )
185.         return true;
186.     return false;
187. }
188.
189. int count_dashes( const string& isbn )
190. {
191.     int len    = isbn.length();
192.     int dashes = 0;
193.     for( int i = 0; i < len; ++i )
194.     {
195.         if( isbn.at( i ) == '-' )
196.             dashes++;
197.     }
198.     return dashes;
199. }
200.
201. int count_digits( const string& isbn )
202. {
203.     int len    = isbn.length();
204.     int digits = 0;
205.     for( int i = 0; i < len; ++i )
206.     {
207.         if( isdigit( isbn.at( i ) ) )
208.             digits++;
209.     }
210.     return digits;
211. }
212.
213. bool is_sequential_dashes( const string& isbn )
214. {
215.     int len    = isbn.length();
216.     for( int i = 0; i < len - 1; ++i )
217.     {
218.         if( isbn.at( i ) == '-' && isbn.at( i + 1 ) == '-' )
219.             return true;
220.     }
221.     return false;
222. }
223.
224. bool is_dashes_at_bad_position( const string& isbn )
225. {
226.     if(
227.         isbn.at( 1 )  != '-' ||
228.         isbn.at( 5 )  != '-' ||
229.         isbn.at( 11 ) != '-'
230.     )
231.         return true;
232.     return false;
233. }
234.
235. int get_check_sum( const string& isbn )
236. {
237.     int len = isbn.length();
238.     int sum = 0;
239.     int cnt = 1;
240.     for( int i = 0; i < len - 1; ++i )
241.     {
242.         if( isdigit( isbn.at( i ) ) )
243.         {
244.             sum += cnt * convert_single_char_to_int( isbn.at( i ) );
245.             cnt++;
246.         }
247.     }
248.     return sum;
249. }
250.
251.
252.
253. void test_isbn( const string& isbn )
254. {
255.     ErrorType er;
256.     int       number_digits = count_digits( isbn );
257.     int       number_dashes = count_dashes( isbn );
258.
259.     if( is_begin_end_dash( isbn ) )
260.     {
261.         er = BEGIN_OR_END_BY_DASH;
262.     }
263.     else if( is_last_digit_invalid( isbn ) )
264.     {
265.         er = WRONG_END_DIGIT;
266.     }
267.     else if( is_sequential_dashes( isbn ) )
268.     {
269.         er = SEQUENTIAL_DASHES;
270.     }
271.     else if( number_digits != MAX_DIGITS )
272.     {
273.         if( number_digits < MAX_DIGITS )
274.             er = NOT_ENOUGH_DIGITS;
275.         else
276.             er = TOO_MANY_DIGITS;
277.     }
278.     else if( number_dashes == MAX_DASHES || number_dashes == 0 )
279.     {
280.         if( number_dashes == MAX_DASHES && is_dashes_at_bad_position( isbn ) )
281.         {
283.         }
284.         else
285.         {
286.             int check_sum  = get_check_sum( isbn );
287.             int last_digit = convert_single_char_to_int( isbn.at( isbn.length() - 1 ) );
288.
289.             if( ( check_sum % ( MAX_DIGITS + 1 ) ) == last_digit )
290.             {
291.                 if( number_dashes == 0 )
292.                     er = OK_BUT_NOT_WELL_FORM;
293.                 else
294.                     er = VALID_AND_WELL_FORM;
295.             }
296.             else
297.             {
298.                 er = WRONG_CHECK_SUM;
299.             }
300.         }
301.     }
302.     else
303.     {
304.         if( number_dashes > MAX_DASHES )
305.             er = TOO_MANY_DASHES;
306.         else
307.             er = NOT_ENOUGH_DASHES;
308.     }
309.
310.     print_error_type_messages( er );
311. }
312.
313.
314.
315. void print_error_type_messages( ErrorType er )
316. {
317.     switch( er )
318.     {
319.     case WRONG_END_DIGIT :
320.         cout << " (Can't have any character except for 'X' at end unless 10 is the remainder)" << endl;
321.         break;
322.     case NOT_ENOUGH_DIGITS :
323.         cout << " (Not enough digits)" << endl;
324.         break;
325.     case TOO_MANY_DIGITS :
326.         cout << " (To many digits)" << endl;
327.         break;
328.     case NOT_ENOUGH_DASHES :
329.         cout << " (Not enough dashes)" << endl;
330.         break;
331.     case TOO_MANY_DASHES :
332.         cout << " (Too many dashes)" << endl;
333.         break;
334.     case WRONG_CHECK_SUM :
335.         cout << " (Wrong check sum)" << endl;
336.         break;
337.     case BEGIN_OR_END_BY_DASH :
338.         cout << " (Beginning or ending dash)" << endl;
339.         break;
340.     case SEQUENTIAL_DASHES :
341.         cout << " (Sequential dashes)" << endl;
342.         break;
344.         cout << " (Dashes at wrong places)" << endl;
345.         break;
346.     case OK_BUT_NOT_WELL_FORM :
347.         cout << " (Good number but not well-formed) " << endl;
348.         break;
349.     default :
350.         cout << " (Good number and well-formed)" << endl;
351.     }
352. }
353.
354. int convert_single_char_to_int( char number )
355. {
356.     if( number == 'x' || number == 'X' )
357.         return 10;
358.     else
359.         return static_cast< int >( number ) - static_cast< int >( '0' );
360. }
361.
362. bool continue_or_quit( const char* mess )
363. {
364.     cout << mess << "\n";
365.     string repl;
366.     while( 1 )
367.     {
368.         cin >> repl;
369.         if( repl.at( 0 ) == 'Y' || repl.at( 0 ) == 'y' )
370.             return true;
371.         else if( repl.at( 0 ) == 'N' || repl.at( 0 ) == 'n' )
372.             return false;
373.         else
374.             cout << "\n Invalid answer. Try again !\n";
375.     }
376. }

3. Awaiting Email Confirmation
Ngày gia nhập
09 2008
Bài viết
16
Code:
```// filename = isbn.cpp

// Prof. Gelotte

// 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

#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()
{
char choice;					// User choice value
char check = 'm';					// 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");
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    // else WHAT>?@#\$(*&@#\$()*#\$&()*!!!
{

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");
}   // end WHAT?!@#*&^#\$@(*&\$#^(&*!!

cout << " " << endl;
check = 'm';

}    // end what?

// 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
int i;
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```
thanks pro morock nhiều lắm, mình tự làm được rồi nè, pro có góp ý gì thêm cho mình hông, mình mới học programming được 5 tuần thôi, mình đang ở Us, người ta bắt đọc nhiều lắm, nhớ không hết luôn, diễn đàn này thiệ bổ ích

4. - Tui nhìn code thì biết chắc cậu không học ở VN ! Mà cậu học ở trường nào thế ? Biết đâu chung trường của nên !
- Học 5 tuần mà viết thế là tốt lắm rồi đây !
- Còn bài cậu thì có nhiều chỗ để bàn :
1. Enum dùng sẽ sáng nghĩ hơn.
2. Hai cái hàm fileinput & userinput có nhiều điểm giống( có thể dùng istream& cho ifstream và cin ). Nhưng code cậu implement khác nhau, dư nhiều code không cần thiết.
3. Cậu nên nhớ là không bao giờ cho input và output vào các function khác.
Ví dụ đoạn :
C++ Code:
1. if (charcount < 10)
2.         cout << " (Not enough digits)" << endl;
3.     if (charcount > 10)
4.         cout << " (To many digits)" << endl;
5.     if (charcount  <  10 && lettercheck == 1)
6.         cout << " (Can't have any character except for 'X' at end unless 10 is the remainder)" << endl;
7.     if (dashcount > 4)
8.         cout << " (Too many dashes)" << endl;
9.     if ((dashcount < 3 && dashcount > 0) && length > 10)
10.         cout << " (Not enough dashes)" << endl;
11.     if (value != digit)
12.         cout << " (Wrong check sum)" << endl;
13.     if (dashstart == 1)
14.         cout << " (Beginning or ending dash)" << endl;
15.     if (doubledash > 0)
16.         cout << " (Sequential dashes)" << endl;
17.     if (spacecount > 4)
18.         cout << " (Too many spaces)" << endl;
19.     if ((spacecount < 3 && spacecount > 0) && length > 10)
20.         cout << " (Not enough spaces)" << endl;
21.     if ((spacecount == 0 || spacecount == 3) && (dashcount == 3 || dashcount == 0) && (charcount == 10) && (counter == 10) && (digit == value))
22.         cout << " (Good number and checksum)" << endl;
23.     else
24.         ;
Giả nếu tui cần chuyển sang tiếng Việt thì cậu nghĩ có bao nhiêu hàm cậu cần phải sữa lại ?
3. Hàm test( string& ) phải là test( const string& ) vì cậu chỉ test chứ không modify string.
4. Test 1 chức năng 1 hàm thì sẽ dễ hơn RẤT RẤT nhiều vì sao ? Vì khi cậu muốn thêm hay bớt cậu không test toàn bộ. Hàm test là quá dài, 1 cái sai thì cá đảm kia chạy bằng niềm tin. Thà cậu paid-off cho function hơn là cậu gom 1 đống vào.
->
5. Khi tui học lớp này, cô tui chấm rất kĩ : chú ý thêm các chỗ thiếu const, và gom những cái chung để ra ngoài. Không để magic number nhiều quá, dùng const int để khai báo nó với 1 cái tên có ý nghĩa hơn. Hàm cách 2 blank line. Main đặt trên đầu, nhớ ghi tên đầy đủ và giới thiệt sơ chương trình trong phần output.
6. Lần sau không post vào box project( đây là nơi chia sẽ mã nguồn ), không phải nơi hỏi ! Dù cậu xài Visual C++ ở trường nhưng cái này là C++ not Visual C++, chú ý post đúng box.
ps : có mod nào move dùm vào box C++ được không ?

#### Quyền hạn của bạn

• Bạn không thể gửi đề tài mới
• Bạn không thể gửi bài trả lời
• Bạn không thể gửi các đính kèm
• Bạn không thể chỉnh sửa bài viết của bạn