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.
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";
First you should check the size of string
if(ISBN.size() != 9){
// ERROR
}
You can use 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
}
}
Related
I am trying to take a user entered integer (positive or negative) and let them pick a digit position and output the digit at that position.
int findDigAtPos(int number)
{
int position;
int result;
cout << "Enter digit position between 1 and " << std::to_string(number).length() << endl;
cin >> position;
while (position < 0 || position > std::to_string(number).length())
{
cout << "Enter digit position between 1 and "<< std::to_string(number).length()<<endl;
cin >> position;
}
if (std::to_string(number).length() == 1)
cout << "Only one digit" << endl;
number = number / pow(10, (position - 1.0));
result = number % 10;
return result;
}
This is the code I currently have for the function. However, it outputs the number in reverse. How do I correct the digit position? I thought it didn't even function correctly until noticing it's in reverse order.
First, note that you shouldn't be using the pow function when working with integers, because it returns a double result, which can cause problems due to unexpected truncation of the result.
But, if you insist on using it, then you need to remember that the power of 10 by which to divide will decrease as the digit position increases: i.e., the position is given with the leftmost (most significant) digit in position 1. Thus, that power of 10 will be total number of digits minus the position:
number = number / pow(10, (std::to_string(number).length() - position));
result = number % 10;
The safer method (not using pow) would be a small loop, like this:
for (int d = std::to_string(number).length() - position; d > 0; --d) number /= 10;
result = number % 10;
However, as you're already converting the passed number to a string, then why not just save that string and extract the digit from it – at position-1, because array (and string) indexes in C++ are zero-based:
int findDigAtPos(int number)
{
int position;
std::string str = std::to_string(std::abs(number)); // If -ve, remove sign!
int ndig = str.length();
std::cout << "Enter digit position between 1 and " << ndig << "\n";
std::cin >> position;
while (position < 0 || position > ndig) {
std::cout << "Enter digit position between 1 and " << ndig << "\n";
std::cin >> position;
}
return str.at(position-1) - '0';
}
Note that the codes (ASCII or otherwise) for the numeric digits, 0 thru 9 are guaranteed by the C++ standard to be contiguous and in order, so subtracting the value of the digit 0 will 'convert' any digit to its actual, numerical value.
Instead of this:
number = number / pow(10, (position - 1.0));
result = number % 10;
This:
int length = (int)(std::to_string(number).length());
while (position < length)
{
number = number / 10;
length--;
}
result = number % 10;
The above should work fine for positive numbers. For negative numbers, you might need to a fixup. I'll leave that as an exercise for you to manage.
This question already has answers here:
Convert char to int in C and C++
(14 answers)
Closed 7 months ago.
char* array{};
string digit4;
cout << "Enter a 4 digit-integer : " << endl;
cin >> digit4;
cout << "The 4 digit-integer you have entered is : " << digit4 << endl;
array = &digit4[0];
cout << "Digit 1 is : " << array[0] << endl;
int digit1 = (array[0] + 7) % 10;
cout << digit1 << endl;
return
I tried to convert a string to an array and use the first digit of array[0] to a formula of ( array[0] + 7 ) % 10. If I input 1234, ( 1 + 7 ) % 10 should be 8 but I'm getting 6 instead of 8. Any help would be great. Thank you for reading.
The expression array[0] evaluates to the character code for the digit '1', which is 49 in ASCII.
Therefore, assuming that you are using ASCII, the expression
(array[0] + 7) % 10;
is equivalent to
(49 + 7) % 10
which is 6.
If you want to get the value that is represented by the digit, then you can simply subtract '0' (which is the character code for the digit '0', which is 48 in ASCII) from the character code of the digit.
Therefore, to solve your problem, you can simply change the line
int digit1 = (array[0] + 7) % 10;
to:
int digit1 = ( array[0] - '0' + 7 ) % 10;
The array[0] is 49 in ascii, when you use + you convert it to int like int(array[0]) which the result is 49. you should convert array[0] to int number like This post
i am a novice to C++ , I was trying to write this program for adding two very large numbers using strings but the program is not working correctly and I can't get what's wrong with it , please help me with this.
#include<iostream>
#include<stack>
#include<string>
using namespace std;
int main() {
stack <char> a1;
stack<char> a2;
stack<int> result;
stack<int> temp;
int carry = 0;
string num1;
string num2;
cout << "Enter first number (both numbers should have equal digits)" << endl;
getline(cin, num1);
cout << "Enter second number" << endl;
getline(cin, num2);
for (int i = num1.size()-1; i >= 0; i--) {
a1.push(num1[i]);
a2.push(num2[i]);
}
while (!a1.empty() && !a2.empty()) {
int element = (int)a1.top() + (int)a2.top() + carry;
cout << element;
if (element > 10) {
element %= 10;
carry = 1;
}
result.push(element);
cout << result.top() << endl;
a1.pop();
a2.pop();
}
string abc;
while (!result.empty()) {
temp.push(result.top());
result.pop();
abc += temp.top();
}
cout << abc;
}
I know i have definitely made a logical mistake , but i can't get it , can anyone please guide me?
the following is the output am getting
I was thinking, why stacks should be used. My guess is that you did this, because the numbers must be processed from right to left.
Additionally, you have obiously a challenge with strings with a different length.
But both problems can be solved easily. Let us start with the different length strings.
If 2 strings have a different length, we can pad (fill in) the shorter string with leading `0's. How many leading '0s' do we need to add? Right, the delta of the lengths.
And for inserting characters in a string at a certain position, we have the function insert.
So, the code for that will look like this:
if (numberAsString1.length() < numberAsString2.length())
numberAsString1.insert(0, numberAsString2.length() - numberAsString2.length(), '0');
else
numberAsString2.insert(0, numberAsString1.length() - numberAsString2.length(), '0');
This is rather straightforward.
The result will always be 2 strings with equal length. With entering "1234" and "9", we will get: "1234" and "0009".
This makes the next task easier.
Now that we have 2 equal length strings, we can "add", like we learned in school.
We go from right to left, by starting with the highest possible index of a character in the string. This is always length-1.
For calculating the sum, we need first to subtract the ASCII code for '0' from the characters in the string, because the string contains not integer numbers, but characters. For example "123" consists of '1', '2', '3' and not of 1,2,3.
Suming up is then easy: digit + digit + carry.
The resulting digit is always the sum % 10. And the next carry is always sum / 10. Example 1: 3+5=8 8%10=8 8/10=0. Example 2: 9+8=17 17%10=7 17/10=1.
So, also this is rather simple.
After we worked on all digits of the strings, there maybe still a set carry. This we will then add to the string.
Adding digits will be done in any case using the instert function. Because we want to insert digits on the left side of the resulting string.
So, with working from right to left, using correct indices and the insert function, we do not have the need for a stack.
With a lot of input checking, the whole function would look like this:
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
int main() {
// Give instruction to user
std::cout << "\nPlease enter 2 positive interger numbers:\n";
// Here we will store the user input
std::string numberAsString1{}, numberAsString2{};
// Get strings from user and check, if that worked
if (std::cin >> numberAsString1 >> numberAsString2) {
// Check if all characters in string 1 are digits
if (std::all_of(numberAsString1.begin(), numberAsString1.end(), std::isdigit)) {
// Check if all characters in string 2 are digits
if (std::all_of(numberAsString2.begin(), numberAsString2.end(), std::isdigit)) {
// ---------------------------------------------------------------------------------
// Here we will store the calculated result
std::string result{};
// Temporary helpers
unsigned int carry{};
// ---------------------------------------------------------------------------------
// Make strings equal length. Pad with leading '0' s
if (numberAsString1.length() < numberAsString2.length())
numberAsString1.insert(0, numberAsString2.length() - numberAsString2.length(), '0');
else
numberAsString2.insert(0, numberAsString1.length() - numberAsString2.length(), '0');
// ---------------------------------------------------------------------------------
// Iterate over all digits from right to left
for (int i = numberAsString1.length()-1; i >= 0; --i) {
// Calculate the sum
const int sum = numberAsString1[i]-'0' + numberAsString2[i] - '0' + carry;
// Get the carry bit in case of overflow
carry = sum / 10;
// Save the resulting digit
result.insert(0, 1, sum % 10 + '0');
}
// handle last carry bit
if (carry) result.insert(0, 1, '1');
// ---------------------------------------------------------------------------------
// Show result
std::cout << "\n\nSum: " << result << '\n';
}
else std::cerr << "\n\nError: number 1 contains illegal characters\n";
}
else std::cerr << "\n\nError: number 2 contains illegal characters\n";
}
else std::cerr << "\n\nError: Problem with input\n";
return 0;
}
I'm trying a lab exercise which wants user to input a 2 4-digit integer. Then the program will extract all the numbers in the 4-digit integer and use the number to do an arithmetic calculation just like the image link below.
Arithmetic Calculation with 2 4-digit integer
However, the objective for this lab exercise is not to allow me myself, to use a for loop to obtain the result.
For instance, when i want to obtain the last number of the 4 digit integer, I could easily do it by using this.
int firstDigit = firstNo % 10; //i will get 4 if the integer is 1234
int secondDigit = secondNo % 10; //i will get 8 if the integer is 5678
And of course table formatting is nothing to worry about before getting the logic right. Next is a very simple calculation of the numbers using the digit i obtain from the above.
int addfirstNumbers = firstDigit + secondDigit;
int minusfirstNumbers = firstDigit - secondDigit;
int multiplefirstNumbers = firstDigit * secondDigit;
int modfirstNumbers = firstDigit % secondDigit;
double divfirstNumbers = firstDigit / secondDigit;
cout << "add: " << addfirstNumbers << endl
<< "minus " << minusfirstNumbers << endl
<< "multipile " << multiplefirstNumbers << endl
<< "remainder " << modfirstNumbers << endl
<< "division " << divfirstNumbers << endl;
I do understand forloop can make my life easier. But i'm just trying out the long method before trying out the shorter way which is forloop.
But even before i proceed, I'm still unable to extract out the other digit from this 4 digit integer.
Like Mike Vine mentioned in the comments, you can do integer division before taking the modulo.
#include <iostream>
int main(){
int x = 1234;
std::cout << (x/10)%10 << "\n";
}
#Output
3
Edit: This works for all places of a number. To find the nth value from the end, just keep adding 0s to the divisor. For example to find the 2nd from the last, you'd want to divide x by 100 instead.
You could simply do
int secondLastDigit = ((i - (i % 10)) % 100)) / 10;
For i=5678:
i % 10 (5678 % 10) equals 8
i - (i % 10) (5678 - 8) therefore equals 5670.
(i - (i % 10)) % 100 (5670 % 100) equals 70
Finally (i - (i % 10)) % 100) / 10 (70 / 10) = 7
This is pretty simple, just use the modulus operator on the number for 100(num%100), getting the last two digits that way, and then divide that result by ten, and store the digit in an int (so the decimal is properly truncated.)
I have an array ( char location[2]; ) This needs to receive two values from the user. The first is a letter the other a number, in that order. This is used to select a location in a 9 x 9 grid.
The grid appears
A B C D E F G H I
1
2
3
4
5
6
7
8
9
When I try to store the second value as an int, The method I would think would work is being set to -48.
int row = location[1] - 48;
48 is the ASCII value of '1'. Shouldn't this have created an int with the value of one less than whatever number was input by the user? '2' (aka 49) - 48 = 1? It always comes out as -48 no matter what the input is.
My full function:
#include <iostream>
using namespace std;
void getLocation(int &column, int &row)
{
int row = 0;
int column = 0;
char location[2];
cout << "location: ";
cin.getline(location,2);
cin.ignore();
cin.clear();
switch (location[0])
{
case 'A':
cout << "case A\n";
column = 0;
break;
case 'B':
cout << "case B\n";
column = 1;
break;
case 'C':
cout << "case C\n";
column = 1;
break;
}
row = location[1] - 48;
cout << "column: "
<< column
<< " row: "
<< row
<< "\n";
}
location[1] - 48 will always be -48 if positive-length string is given because terminating null-character will be stored there. Allocate enough length to store the input. You are using C++, so using std::string is better to store strings than using arrays of char.
cin.getline(location,2) does not behave in the way you expect.
It writes a nul-terminated string to location i.e. location[0] is read from cin, and location[1] receives a character with value of 0 (numeric zero, not '0').
0 - 48 always produces a result of -48 as an int.
Note, also, that '1' is not guaranteed to have a value of 48. '0' does in ASCII and compatible character sets. Other character sets will give different values.
You would be better off using std::string - that eliminates the need to worry about arrays of char and nul termination.
The size of the stream for cin.getline needs space for a null terminator. Therefore, increase the size of the stream buffer and terminate input on the carriage return:
cin.getline(location, 3, '\r');