Problem converting a std::string of digits to vector<int> [duplicate] - c++

This question already has answers here:
C++ handling very large integers
(15 answers)
Closed 3 years ago.
I am supposed to get two big integer numbers (up to 600 digits) from console screen and write the result on the console again.
I defined two variables of type std::string to store two big integer numbers .I take their values from the user. To take the sum of that two numbers, I defined two vectors to store the digits of that two strings of numbers .
Here is the problem, when I try to loop through the vector to print the digits that I took from strings of numbers I get the following result .The Ascii values of the digits are printed on The Console.
Could anyone tell me how to fix this problem please.
Note: The code is still not complete .
For the first string I took the numbers 9 8 7 6 5 4 3 2 1 from the user , on the console window I got the following result.
[0]57
[1]56
[2]55
[3]54
[4]53
[5]52
[6]51
[7]50
[8]49
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
std::string Sum_Of_Two_Long_Integers()
{
std::string First_String ;
std::string Second_String ;
std::string Result_String ;
std::cout << "Please enter the first number: " ;
std::getline(std::cin, First_String);
std::cout << "Please enter the second number: " ;
std::getline(std::cin, Second_String);
std::vector <int> First_String_Vector (First_String.length()) ;
std::vector <int> Second_String_Vector (Second_String.length()) ;
for(int Counter = 0 ; Counter < First_String_Vector.size() ; ++ Counter)
{
First_String_Vector[Counter] = First_String[Counter] ;
Second_String_Vector[Counter] = Second_String[Counter] ;
std::cout << "[" << Counter << "]" << First_String_Vector[Counter] << std::endl ;
}
return Result_String ;
}
int main()
{
std::string Result_String = Sum_Of_Two_Long_Integers() ;
std::cout << "Result = " << Result_String << std::endl ;
return 0 ;
}

First_String_Vector[Counter] = First_String[Counter] ;
Second_String_Vector[Counter] = Second_String[Counter] ;
The digits are stored as ASCII in you string, you should convert to integer before placing them into the vector.
This would do the trick:
First_String_Vector[Counter] = First_String[Counter] - '0';
Second_String_Vector[Counter] = Second_String[Counter] - '0';
I would also add a check for valid input before populating your vectors to make sure that you only read digits:
if(First_String[Counter] < '0' || First_String[Counter] > '9' ||
Second_String[Counter] < '0' || Second_String[Counter] > '9')
{
std::cout << "Invalid input\n";
return "":// Or better throw an exception
}
EDIT: '6' isn't equal to 6. The first one is a char, its value is ASCII for character '6', and the second is the integer 6.
ASCII is an encoding. Characters are mapped to some numbers. Value for '0' is 48, '1' is 49, ..., '9' is 57
To be even more precise C++ does not guarantee to use ASCII encoding (though I don't know of an implementation that does not use it), but it does guarantee that '0'...'9' have contiguous integer values. So '6' - '0' will give us integer 6.

Related

Why is negative char number converting differently?

I need to convert characters from a string into int's then place them into a vector. I started by making a new string of the numbers without the spaces. I then want to iterate through the numbers in the result string and convert to int, then push into a vector. I am having issues with the negative numbers not converting to the right values. I commented out the vector part because I realized the issue is before that, the wrong values are going into the vector.
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
int main() {
string result = "";
string str = "8 3 -5 42 -1 0 0 -9 4 7 4 -4";
for(char c : str) {
if(c == ' ') {
continue;
}
else {
result += c;
}
}
cout << "result: " << result;
vector<int> lst;
//for(int x = 0; x < result.length(); x++) {
//lst.push_back(result[x] - '0');
//}
//testing the values being converted
int x = result[2] - '0';
cout << "\n" << x;
}
For example,
int x = result[0] - '0';
cout << "\n" << x;
gives me 8, which is the right conversion of the first number in the string.
but,
int x = result[2] - '0';
cout << "\n" << x;
gives me -3, which is not the -5 I am looking for. I am stuck on this and I cannot figure out why the negative numbers are not properly converting, or where the -3 is even coming from. Any help is appreciated, thank you.
Your input is: "8 3 -5 42 -1 0 0 -9 4 7 4 -4"
You put non-space characters into the result array, so:
result[0]->'8'
result[1]->'3'
result[2]->'-'
result[3]->'5'
So result[2] is - which has an ASCII code of 45. The zero digit has an ASCII code of 48. So result[2] - '0' is 45 minus 48 or -3.
You don't say why you expect -5. What character do you think is five less than the digit zero?

Issue with str.push_back

I am trying to create a C++ function with the following behavior:
Input: "A4B5C3" ; Output: "AAAABBBBBCCC"
Input: "R1T3" ; Output: "RTTT"
And so on.
I have written the following function:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
string foo(string s){
int count = 0;
string t = "";
char letter = 'a';
for (string::iterator it=s.begin(); it<s.end(); it++){
if(count%2==0)
{
cout << "count: "<<count << " *it: "<< *it << endl;
letter = *it;
}
else
{
cout <<"count: "<< count << " *it: " << *it << " letter: " << letter << endl;
int j = 0;
while (j<*it)
{
t.push_back(letter);
j++;
}
}
count++;
}
cout << endl<<endl;
return(t);
}
However , on calling foo("A1B4C2D8"), I get this output:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
For some reason, my while loop seems to be running 48 more times than I would like it to...
There are no character encodings where the integer 1 is equal to the character '1' (for example).
In the ASCII encoding the character '1' is equal to the integer 49.
That means the condition j<*it is flawed.
The C++ specification requires that all digits are encoded consecutively, so '0' will always come before '1', and '1' will always come before '2', and so on. With that knowledge, together with knowing that char is a simple integer type, you can always subtract '0' from any digit character to get its integer value.
For example '2' - '0' == 2.
To solve your problem the condition should be j < (*it - '0').
Here :
while (j< *it)
you are comparing an integer (int) with a character (char). The character '0' does not equal 0, but as digits have consecutive representations you can subtract '0' from the character to get the corresponding integer:
while (j< *it - '0')
Issue is in the line
int j = 0;
while (j<*it)
...
You are comparing the int value with the chacter.
The character '0' in ASCII encoding has the hexadecimal integer value 0x30 and the decimal integer value 48. The character '1' has the hexadecimal integer value 0x31 and the decimal integer value 49. And so on till '9' that has the hexadecimal integer value 0x39 and the decimal integer value 57.
Even not knowing those ASCII codes the shortest fix is changing int j = 0; to int j = '0'; or char j = '0';. Then the loop while (j < *it) will iterate correctly.

Adding to very large numbers using stack

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;
}

converting a char variable in an array to an int C++

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');

Why does my string get empty values appended to it when subtracting characters?

I am attempting to solve a problem from topcoder.com and it's driving me crazy. I am learning C++ after a long break from C and am having trouble with strings.
The purpose of the program is to decode a string of 0s and 1s that has gone through an encryption algorithm that consists of adding each adjacent digit to the digit in question.
So 010111 becomes 112232 (LSB and MSB are considered to have zeros next to them). Below is my algorithm to decode the string:
#include <string>
#include <vector>
#include <iostream>
using namespace std;
class BinaryCode {
public:
vector<string> decode(string message);
};
vector<string> BinaryCode::decode(string message) {
vector<string> decoded(2);
int i;
string myTempString;
myTempString.append("0");
myTempString.append(1,message[0] - myTempString[0]);
for(i=2; i<message.size(); i++) {
myTempString.append(1,message[i-1] - myTempString[i-1] - myTempString[i-2]);
}
decoded[0] = myTempString;
myTempString = "";
myTempString.append("1");
myTempString.append(1,message[0] - myTempString[0]);
for(i=2; i<message.size(); i++) {
myTempString.append(1, message[i-1] - myTempString[i-1] - myTempString[i-2]);
}
decoded[1] = myTempString;
return decoded;
}
int main () {
string message("123210122");
BinaryCode *code = new BinaryCode;
vector<string> result = code->decode(message);
cout << "Decoded strings are "+result[0]+" and "+result[1];
getchar();
return 0;
}
The output is nonsense:
Decoded strings are 01
This is just a guess, since you don't show what output you're getting, but it looks like you're doing math on the character values and ending up with characters in the control range. For example, '1' - '0' is not '1' (character 49), it is 1, or Control-A. This is not printable and will typically be invisible in the output. Similarly, '1' + '2' is 49 + 50, or 99, which is 'c'. C++ is not going to magically convert these characters to integers for you. Hopefully this will give you the information you need to fix your code.
A character is an 8-bit integral type. It has the special property that, when printed, it will appear as the character that matches the ASCII value that it contains.
For example:
int valueAsInt = 65;
char valueAsChar = valueAsInt;
std::cout << valueAsChar << "\n";
valueAsInt = 'A';
std::cout << valueAsInt << "\n";
A
65
Take the value of the character literal '0'. This corresponds to the ASCII value 48. '1' is 49, etc.
If you subtract 48 from 49, you get 1. But that's not what you're looking for.
The ASCII value 1 corresponds to a non-printable character, called "start of heading". It was once used on old printers as a sort of markup. It would not print, but it would modify how further characters are printed.
When you subtract one numeric character from another, you get a delta, not a printable character. To turn this delta back into a printable character, you have to add it to a base character:
char value = '5' - '3';
value += '0';
std::cout << "5 - 3 = " << value << "\n";
5 - 3 = 2
So, your code such as message[0] - myTempString[0] must be changed to message[0] - myTempString[0] + '0' in order to work the way you intend it to.