Это все более или менее объяснимо.
int main(){
std::string bigNumber = "93485720394857230";
Эта строка копирует один символ '5' в символьную переменную. atoi
преобразует это правильно. atoi
ожидает, что строковым параметром является допустимая строка с нулем в конце. &tmp
является только указателем на символьную переменную - поведение этого вызова не определено, поскольку память, следующая непосредственно за символом в памяти, неизвестна. Точнее, вам нужно будет создать строку с нулевым символом в конце и передать ее. *
char tmp = bigNumber.at(5);
int digit = atoi(&tmp);
Эта строка получает указатель на символ в позиции 5 в строке. Это указатель на исходную строку большого числа выше - поэтому строковый параметр atoi
выглядит как строка "5720394857230". atoi
явно переполнит поток, пытаясь превратить это в целое число, поскольку ни одно 32-битное целое не будет содержать это.
int digit2 = atoi(&bigNumber.at(5))
Эта строка получает указатель на строку в позиции 12. Параметр atoi
является строкой.
"57230". Правильно преобразуется в целое число 57230.
int digit3 = atoi(&bigNumber.at(12));
...
} * * Тысяча двадцать-один
Поскольку вы используете C ++, есть более приятные методы для преобразования строк символов в целые числа. Я неравнодушен к библиотеке Boost lexical_cast. Вы бы использовали это так:
char tmp = bigNumber.at(5);
// convert the character to a string then to an integer
int digit = boost::lexical_cast<int>(std::string(tmp));
// this copies the whole target string at position 5 and then attempts conversion
// if the conversion fails, then a bad_lexical_cast is thrown
int digit2=boost::lexical_cast<int>(std::string(bigNumber.at(5)));
* Строго говоря, atoi
будет сканировать числовые символы, пока не будет найден нечисловой. Он явно не определен, когда он найдет его и что он будет делать при чтении из недопустимых областей памяти.