Какая польза от scanf () == 1? - PullRequest
1 голос
/ 13 марта 2020

Мой код:

while(scanf("%f", &number) && number > 0) 
while(scanf("%f", &number) == 1 && number > 0)

Что значит == 1 и нужно ли это?

Ответы [ 2 ]

2 голосов
/ 13 марта 2020

Как указано Флюгер в комментариях , значение ==1 важно, если scanf() возвращает EOF (Конец файла или -1), который будет оцениваться в true, и поскольку значение в number остается неизменным по сравнению с предыдущей итерацией, условие while l oop будет оценено как true.

Это не подходит, так как тогда у нас есть ошибка при сканировании, и условие должно быть false или 0.

1 голос
/ 13 марта 2020

Цитирование из fscanf,

После успешного завершения эти функции должны возвращать количество успешно сопоставленных и назначенных элементов ввода; это число может быть нулевым в случае неудачного раннего сопоставления. Если ввод заканчивается до первого неудачного или конверсионного совпадения, EOF должен быть возвращен. Если происходит ошибка чтения, устанавливается индикатор ошибки для потока, должен быть возвращен EOF, [GNU start] и errno должны быть установлены для указания ошибки. [GNU end]

while(scanf("%f", &number) && number > 0)
while(scanf("%f", &number) == 1 && number > 0)

Здесь scanf может возвращать:

  • -1: конец потока (EOF) или ошибка чтения , (если кто-то хочет дифференцировать последний случай, см. ferror(stdin) или !feof(stdin), а в системах, соответствующих POSIX, будет установлено errno)
  • 0: ошибка сопоставления и
  • 1: успешно сопоставленное число с плавающей запятой, которое хранится в number.

Следовательно,

  1. Первые scanf("%f", &number) [!= 0] && ... проверяют, что он не равен нулю, соответствует "%f". На 1, в случае одной переменной, она будет работать, как и ожидалось, но на -1 она идет по короткому замыканию для чтения из неинициализированной памяти; при следующем вызове scanf он, вероятно, зависнет в ожидании ввода от stdin, который (скорее всего) был закрыт.

  2. Второй scanf("%f", &number) == 1 && ... явно подтверждает, что переменная был написан, прежде чем перейти к следующему утверждению. Это более надежное решение, которое позаботится о совместимости и чтении ошибок, и будет работать правильно, перейдя ко второму предикату, чтобы проверить, находится ли он в домене.

Однако он не записывает почему l oop остановился, и последующие чтения могут иметь проблемы. Чтобы получить эту информацию, присвойте переменную возвращаемому значению scanf или switch scanf.

...