Проверить целое число против символов - PullRequest
0 голосов
/ 28 марта 2019

Я пытаюсь создать программу, в которой пользователь вводит значение в массив. Что на самом деле требуется, так это то, что программа должна проверять соответствие символу char. Поэтому, если пользователь вводит случайный символ, такой как 'n', программа должна сказать ему: «Вы ввели символ, пожалуйста, введите целое число:».

Как это возможно сделать без использования переменной char?

for (i = 1; i <= size; i++) {
      printf("Introduce the value #%d of the list: ", i);
      scanf("%d", &list[i]);
      if () { // I'm blocked right in this line of code.
        printf("What you tried to introduce is a char, please input an integer: ");
        scanf("%d", &list[i]);
      }

Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 28 марта 2019

Как говорит @MFisherKDX, проверьте возвращаемое значение scanf. Со страницы руководства scanf :

Эти функции возвращают количество элементов ввода, которые были успешно сопоставлены и назначенный, который может быть меньше, чем предусмотрено, или даже ноль в событие раннего неудачного сопоставления.

Значение EOF возвращается, если конец ввода достигнут до того, как происходит первое успешное преобразование или сбой сопоставления. EOF это также возвращается, если происходит ошибка чтения, в этом случае ошибка индикатор для потока (см. ferror (3)) установлен, и errno установлен указать ошибку.

Таким образом, захват возвращаемого значения scanf в переменной int и последующее сравнение этой переменной с 1 (в вашем случае, потому что вы пытаетесь прочитать только 1 элемент) должны сообщить вам, успешно ли scanf читать целочисленное значение.

Однако при использовании scanf есть неприятная ловушка , о которой вам следует знать. Если вы введете n в командной строке, scanf завершится неудачно и вернет 0, но оно также будет не потреблять введенный вами ввод. Это означает, что при следующем вызове scanf он будет читать тот же ввод (введенный вами символ n) и снова не выполнится. И это будет продолжаться независимо от того, сколько раз вы звоните scanf. Меня всегда удивляет, что преподаватели компьютерных наук продолжают преподавать scanf студентам, учитывая не только эту потенциальную ловушку, но и несколько других ловушек . Хотелось бы, чтобы у меня был никель на каждый час , который какой-то студент CS изучал где-то изо всех сил, пытаясь заставить scanf вести себя так, как подсказывает их интуиция. Я бы уже вышел на пенсию на своем частном острове. Но я отвлекся.

Один из способов обойти эту конкретную ловушку - проверить, не удалось ли scanf, и, если да, преднамеренно потреблять и отбрасывать весь ввод от stdin до следующего символа новой строки или EOF, в зависимости от того, что наступит раньше.

Сначала давайте рассмотрим некоторый un фиксированный код, который вызывает бесконечный цикл, если вы введете нецелое число в качестве ввода:

// Typing the letter 'n' and hitting <Enter> here causes an infinite loop:
int num, status;
while (1) {
  printf("Enter a number: ");
  status = scanf("%d", &num);
  if (status == 1)
    printf("OK\n");
  else
    printf("Invalid number\n");
}

Приведенный выше код (после того, как вы наберете n и нажмете <Enter>), войдет в бесконечный цикл и просто начнет извергать «Неверное число» снова и снова. Опять же, это потому, что введенный вами n никогда не удаляется из буфера ввода.

Есть несколько возможных способов обойти эту проблему , но, по-видимому, все согласны с тем, что наиболее переносимый и надежный способ сделать это заключается в следующем:

// Fixed. No more infinite loop.
int num, status;
while (1) {
  printf("Enter a number: ");
  status = scanf("%d", &num);
  if (status == 1)
    printf("OK\n");
  else {
    printf("Invalid number\n");
    // Consume the bad input, so it doesn't keep getting re-read by scanf
    int ch;
    while ((ch = getchar()) != '\n' && ch != EOF) ;
    if (ch == EOF) break;
  }
}
0 голосов
/ 28 марта 2019

Функция scanf() возвращает количество прочитанных элементов, поэтому в этом случае она будет возвращать 1 при каждом чтении целого числа и 0 при чтении символа, поэтому вам просто нужно проверить это возвращаемое значение. Имейте в виду, что после чтения символа он останется в буфере, поэтому, если вы снова введете команду scanf(), он снова будет читать символ и повторять ошибку. Чтобы избежать этого вам нужно потреблять персонажа с while(getchar() != '\n');

Имея это в виду, я изменил ваш код, чтобы он работал правильно, печатая сообщение об ошибке, если вводится символ, и запрашивая новый int.

for (int i = 1; i <= size; i++) {
      printf("Introduce the value #%d of the list: ", i);
      while (!scanf("%d", &list[i])) { //verifies the return of scanf
        while(getchar() != '\n'); //consumes the character in case of error
        printf("What you tried to introduce is a char\n");
        printf("please introduce the value #%d of the list: ", i);
      }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...