При вводе данных пользователем в C или при чтении из текстового файла все вводимые данные - это ввод символов - даже если эти символы читаются как "123"
(что будет символами ASCII '1'
, '2'
и '3'
) Если вы посмотрите на таблицу ASCII и описание , то увидите, что цифры, состоящие из цифр, имеют значения ASCII (отображаются в десятичном, восьмеричном и шестнадцатеричном виде):
Char Dec Oct Hex
---------------------
0 48 0060 0x30
1 49 0061 0x31
2 50 0062 0x32
3 51 0063 0x33
4 52 0064 0x34
5 53 0065 0x35
6 54 0066 0x36
7 55 0067 0x37
8 56 0070 0x38
9 57 0071 0x39
Те это просто коды ASCII для каждого из символов '0' - '9'
, показанных выше
Итак, вы читаете символ ASCII, одну из цифр с getchar()
, и как получить целочисленное значение для этого ди git? То есть как вы превращаете символ '1
в целое число 1
? Поскольку символ ASCII для '0'
имеет десятичное значение ASCII 48
, если вы хотите получить целое число 0
из ASCII di git '0'
, вы просто вычитаете значение символа ASCII для '0'
от него. (что означает, что, когда вы не понимаете, как получить целое число 0
от символа '0'
, вы просто вычитаете его из себя, оставляя ноль.
Для других цифр ASCII '1' - '9'
обратите внимание на их порядок в последовательность после '0'
в наборе символов.Так что если ASCII '1'
имеет десятичное значение 49
и вы хотите получить из него целое значение 1
, какое число вы должны вычесть из 49
до конца с 1
? (подсказка: 48
или читаемое '0'
). Таким образом, все вычитание значения ASCII для 0
из вашего ASCII di git приводит к преобразованию этого ASCII di git к его целочисленному значению.
Лог c вашего кода неплох, но он написан очень неловко. Всякий раз, когда у вас есть вопрос о том, как работает функция C, прочитайте man-страницу для этой функции, например, man 3 fget c. Там вы увидите, что тип возвращаемого значения для getchar()
уже int
, поэтому нет необходимости приводить возвращение getchar()
к (int)
, это лишнее.
Ваш л * 108 2 * просто умножает текущее значение number
на 10
и затем добавляет новое целое число к этому числу, чтобы вы строили окончательное целочисленное значение из каждой цифры ASCII, которую вы читаете из ввода. Вместо ручного сравнения (0 <= digit && digit <= 9)
заголовок <ctype.h>
предоставляет макрос isdigit()
, который обеспечивает этот тест стандартным способом. Кроме того, как отмечено в комментариях, не делайте - 48
вместо того, чтобы делать то, что вы делаете, читабельным, используя символьный литерал , например digit - '0'
, который легко распознается как преобразование ASCII-ди git до целочисленного значения.
Собрав все эти части вместе, вы можете сделать что-то вроде:
#include <stdio.h>
#include <ctype.h>
int main (void) {
int digit = getchar(), /* read 1st character from stdin */
number = 0; /* initialize number zero */
if (digit == EOF || !isdigit(digit)) { /* validate not EOF and digit */
fputs ("error: manual EOF or non-digit input.\n", stderr);
return 1;
}
digit -= '0'; /* subtract ASCII val for '0' from digit to obtain integer value */
while (1) { /* loop continually reading digits */
number = number * 10 + digit; /* add current digit to number */
if (!isdigit(digit = getchar())) /* read next digit, validate digit */
break; /* on non-digit; break loop */
digit -= '0'; /* subtract '0' for integer value */
}
printf("%d\n", number); /* output integer that results from digit conversion */
}
Пример использования / Вывод
С некоторыми примерами чисел и букв вы можете увидеть, как эта функция должна была работать:
$ echo "135" | ./bin/atoimin
135
$ echo "23a" | ./bin/atoimin
23
( примечание: , как останавливается извлечение символов, если не-di git найдено после того, как di git уже обработан.)
Но посмотрите, что произойдет, когда non-di git будет первым прочитанным символом:
$ echo "a23" | ./bin/atoimin
error: manual EOF or non-digit input.
Просмотрите код и логи c и дайте мне знать, если у вас есть дополнительные вопросы.