Scanf хранит неверное значение в целочисленной переменной - PullRequest
0 голосов
/ 04 ноября 2019

Я написал следующий код, используя язык программирования c (Стандарт 89):

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int cc,dd;
    scanf("%d/%d",&cc,&dd);

    int ll;
    scanf("%d",&ll);
    printf("Value of ll is: %d",ll);
    return 0;
}

Если я отправлю следующее в качестве ввода в одну строку: 4/5h Я получу следующий вывод: Value of ll is: 67 Итак, у меня есть 2 вопроса:

1) откуда взялась эта ценность 67? (Я попытался изменить ввод на что-то вроде 1 / 2t, но получил тот же результат) Согласно тому, что я прочитал, поскольку в буфере нет целых чисел, приложение должно подождать, пока оно не станет доступным (например, для ожидания нового ввода)

2) Когда я запускаю свой код в режиме отладки, я вижу, что значение ll будет 65, а не 67!

1 Ответ

0 голосов
/ 04 ноября 2019

Вводя нецифровые символы в записи, такие как "5h" или "2t" для dd, вы запутываете чтение для ll во втором scanf вызове.

%d говорит scanf пропустить любой начальный пробел, а затем прочитать десятичные цифры до первого нецифрового символа. Если вы введете строку типа "5h" или "2t", эта начальная цифра будет успешно преобразована и присвоена dd, но завершающий нецифровый символ останется во входном потоке, а это загрязнение чтения для ll. В ll не читается новое значение, вы получаете любое неопределенное значение, которое оно имело при запуске программы.

Всегда проверяйте результат scanffscanf и sscanf) - если это меньше, чем ожидаемое количество входов, то у вас есть соответствиеошибка (некоторые входные данные обрабатываются неправильно). Если это EOF, значит, у вас возникла ошибка в самом входном потоке.

В этом конкретном случае вы можете обойти проблему, проверив результат scanf - если это 0, то в потоке есть плохой символ. Выбросьте его и попробуйте снова:

int r;
while ( ( r = scanf( "%d", &ll ) ) != 1 && r != EOF ) 
  getchar();                      

Это вызовет scanf и попытается прочитать значение в ll. Мы ожидаем, что scanf вернет 1 при успешном вводе, поэтому мы зациклимся, пока результат scanf не 1 (and isn 'т EOF, либо). Если чтение не прошло успешно, мы предполагаем, что во входном потоке застрял нецифровый символ, поэтому мы читаем и отбрасываем его с помощью вызова getchar.

...