Reputation: 77
Sorry if this is a dumb question, this is my first coding class.
If the checksum is 10, the last digit is denoted as X according to the ISBN-10 convention. Write a program that prompts the user to enter the first 9 digits and displays the 10-digit ISBN (including leading zeros). Your program should read the input as an integer.
A sample run should look something like this:
Enter the first nine digits of the ISBN: 013601267
The ISBN-10 number is: 0136012671
I have successfully made a program that can do this but using int value for all nine numbers. Unfortunately, this required the user to input every number separately.
So what I am trying to do now is use use a string ISBN
so that I can target individual sections ie. isbn[0] * 1 + isbn[1] * 2...
I have also tried static_cast<char>(ISBN[0]) * 1 + static_cast<char>....
thinking it would do something and I get the same results.
string ISBN;
cout << "Enter the first nine digits of the ISBN as integer: ";
cin>>ISBN;
int n10 = (ISBN[0] * 1 + ISBN[1] * 2 + ISBN[2] * 3 + ISBN[3] * 4 + ISBN[4] * 5 + ISBN[5] * 6 + ISBN[6] * 7 + ISBN[7] * 8 + ISBN[8] * 9) % 11;
if (n10 == 10)
{
cout << ISBN << "X" << endl;
}
else
{
cout << ISBN << n10 << endl;
}
So when I input this number 013601267
I should get a 1 (0136012671)
at the end instead I am getting a 5 (0136012675)
.
I think this is happening because it is giving me ASCII dec value instead of the char
value.
Upvotes: 2
Views: 118
Reputation: 264331
Four things you should check:
1: The size of the string is actually 9 characters.
if (ISBN.size() != 9) {
// Error
}
Otherwise accessing elements that do not exist will cause an error in your program.
2: The digits do not start at value 0
. In ASCII (or UTF-8) the digits start at 48. Therefore 48 => '0' 49 => '1' etc. But C++ guarantees all the digits are contiguous so as long as you know the first one you can subtract that and get a correct value. If you use '0'
in an integer expression it will convert to the correct value. Thus to generate a number value from a char
you should subtract this value from each digit before multiplying.
n10 = ((ISBN[0] - '0') * 1) + ((ISBN[1] - '0') * 2) + ...
3: But you should check the string is all digits.
for(auto x: ISBN) {
if (!std::is_digit(x)) {
// ERROR
}
}
4: To print a string of 9 characters with leading zero you need to make sure you prep the stream coreectly:
std::cout << std::setw(9) << std::setfill('0') << number;
Or if the number is already in a string form that you know is 9 characters long you can simply use:
std::cout << ISBN;
So To output the correct 10 character number in your case:
std::cout << ISBN << ((n10 == 10) ? 'X' : ('0' + n10)) << "\n";
Upvotes: 1
Reputation: 31
if(ISBN.size() != 9){
// ERROR
}
for
to calculate 'n10'int n10 = 0;
for(int i = 0; i < ISBN.size(); ++i){
if(std::is_digit(x)){ // check digit
// characters '0','1','2'... are not same as digits 0, 1, 2...
// the value of '0' is 48, as shown here [ascii table][1]
n10 = (ISBN[i] - '0') * (i+1) + n10;
} else {
// ERROR
}
}
Upvotes: 0