Кто-нибудь может объяснить, как здесь используется getchar для ввода последовательности чисел? - PullRequest
0 голосов
/ 01 апреля 2020

Кто-нибудь может объяснить, как здесь используется getchar для ввода последовательности чисел?

main()
{
  int digit;
  int number;

  digit = (int) getchar() - 48;
  number = 0;

  for (; (digit >= 0) && (digit <= 9); ) 
  {
    number = number * 10 + digit;
    digit = (int) getchar() - 48;
  }

  printf("%d\n", number);
}

Ответы [ 2 ]

1 голос
/ 01 апреля 2020

При вводе данных пользователем в 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 и дайте мне знать, если у вас есть дополнительные вопросы.

0 голосов
/ 01 апреля 2020

См. Пример кода ниже

#include<stdio.h>

int main()
{
    int n=0;
    char ch=getchar();
    n=(ch-'0');
    printf("%d",n);
    return 0;
}

Примечание: Ваш ввод должен быть 1 di git и только диапазон 0-9.

Пусть, как предполагается, вы вводите 5 и Ascii значение '5' равно 53, а значение ascii '0' равно 48

, поэтому

    53-48=5

, поэтому значение n равно 5.

...