I have a big number stored in a string and try to extract a single digit. But what are the differences between those calls?
#include <iostream>
#include <string>
int main(){
std::string bigNumber = "93485720394857230";
char tmp = bigNumber.at(5);
int digit = atoi(&tmp);
int digit2 = atoi(&bigNumber.at(5))
int digit3 = atoi(&bigNumber.at(12));
std::cout << "digit: " << digit << std::endl;
std::cout << "digit2: " << digit2 << std::endl;
std::cout << "digit3: " << digit3 << std::endl;
}
This will produce the following output.
digit: 7
digit2: 2147483647
digit3: 57230
The first one is the desired result. The second one seems to me to be a random number, which I cannot find in the string. The third one is the end of the string, but not just a single digit as I expected, but up from the 12th index to the end of the string. Can somebody explain the different outputs to me?
EDIT: Would this be an acceptable solution?
char tmp[2] = {bigNumber.at(5), '\0'};
int digit = atoi(tmp);
std::cout << "digit: " << digit << std::endl;
It is all more or less explicable.
This line copies the single character ‘5’ into the character variable.
atoiwill convert this correctly.atoiexpects that the string parameter is a valid 0 terminated string.&tmpis only a pointer to the character variable – the behaviour of this call is undefined since the memory immediately following the character in memory is unknown. To be exact, you would have to create a null terminated string and pass that in.*This line gets a pointer to the character in position 5 in the string. This happens to be a pointer into the original big number string above – so the string parameter to
atoilooks like the string “5720394857230”.atoiwill clearly oveflow trying to turn this into an integer since no 32 bit integer will hold this.This line gets a pointer into the string at position 12. The parameter to
atoiis the string“57230”. This is converted into the integer 57230 correctly.
…
}
Since you are using C++, there are nicer methods to convert strings of characters into integers. One that I am partial to is the Boost lexical_cast library. You would use it like this:
* Strictly,
atoiwill scan through the numeric characters until a non-numeric one is found. It is clearly undefined when it would find one and what it will do when reading over invalid memory locations.