Я работаю над проектом CS, и меня смущает какой-то аспект кода.
Я попытался использовать «0», чтобы удалить символьное значение, хранящееся в fDig, и sDig для хранения целых чисел вместо символьных байтов, но каким-то образом, когда я сделал расстояние отрицательным, cerr прочитал какое-то случайное число, не предназначенное снова.
else{
int fDig = commandString[i+1+extra]-'0';
int sDig = commandString[i+2+extra]-'0';
int distance = fDig;
if (isdigit(commandString[i+2])){distance = (fDig*10 + sDig);}
if (extra == 1){distance = -distance;}
cerr << distance << endl;
}
Например, если commandString в i+1+extra равно 3, а commandString в i+2+extra ничего нет, а это extra равно 1. Я получаю значение 18 в качестве вывода для расстояния.
1 ответ
Вычитание '0'
волшебным образом не превращает символ в строке в целое число.
Вычитая '0'
, вы вычитаете из значения ASCII, чтобы получить смещение от ASCII 0:
'0' - '0' = 0x30 - 0x30 = 0
'1' - '0' = 0x31 - 0x30 = 1
'2' - '0' = 0x32 - 0x30 = 2
'3' - '0' = 0x33 - 0x30 = 3
...
'9' - '1' = 0x39 - 0x30 = 9
Однако, если у вас есть мусорные данные (которые вы всегда должны предполагать при вводе пользователем), вы получите мусорные результаты:
'-' - '0' = 0x2d - 0x30 = -3
' ' - '0' = 0x20 - 0x30 = -16
'\0' - '0' = 0x00 - 0x30 = -48 (string terminator)
'\n' - '0' = 0x0a - 0x30 = -38
В стандартной библиотеке C/C++ есть много инструментов, написанных для этого.
Не беспокойтесь об разборе ASCII, если вы АБСОЛЮТНО не знаете, что делаете.
Для одного номера я предлагаю strtoll
для C строки и stoll
для std::strings
, или для нескольких номеров в одной строке sscanf
и istringstream
.
Они обрабатывают шестнадцатеричные, отрицательные, восьмеричные, дополнительные пробелы и обработку ошибок, если вы используете их правильно, и намного, намного, НАМНОГО проще, чем ручной анализ.
Похожие вопросы
Новые вопросы
character-encoding
Кодировка символов относится к способу представления символов в виде последовательности байтов. Кодировка символов для Интернета определяется в стандарте кодирования.