Вызов scanf("%lf", &something)
заполняет something
тогда и только тогда, когда ввод является действительным числом с плавающей запятой. Строка none
- это , а не , такое действительное число.
Причина, по которой вы получаете два значения 3
, вероятно, заключается в том, что nan
является допустимым число с плавающей запятой, поэтому scanf
находит n
и говорит: "Ха, это будет nan
". Но затем он находит, к большому разочарованию, o
и решает, что он больше не действителен.
Но он уже прочитал no
из входного потока. Затем он возвращается и делает то же самое с ne
(a) .
После этого вы снова начинаете давать ему действительные номера, чтобы он продолжал.
Если вы хотите иметь возможность обрабатывать строки и чисел, вам придется использовать наименее ограничивающий (строка), а затем принять решение. Примерно так (хотя scanf("%s")
опасно для реального кода, это, вероятно, нормально для работы с классами):
Следующий код делает это и (как следует) проверяет возвращаемое значение из scanf/sscanf
, чтобы убедиться, что оно было правильно отсканировано:
#include <stdio.h>
#include <string.h>
int main() {
static char bigstring[1000];
double sc[5];
for (int i = 0; i < 5; i++) {
sc[i] = 3;
if (scanf("%s", bigstring) != 1) {
puts("*** Could not get input");
return 1;
}
if (strcmp("none", bigstring) == 0) {
puts("Got 'none', converting to -999");
sc[i] = -999;
} else if (sscanf(bigstring, "%lf", &sc[i]) != 1) {
printf("*** Could not convert input '%s' to float", bigstring);
return 1;
} else {
printf("Got %f\n", sc[i]);
}
}
puts("\nThe five entered numbers were:");
for (int i = 0; i < 5; i++) {
printf(" %lf\n", sc[i]);
}
}
Запуск, который работает правильно с основными c тестовыми данными:
pax:~$ printf "34\nnone\n56\n89\n111\n" | ./qq
Got 34.000000
Got 'none', converting to -999
Got 56.000000
Got 89.000000
Got 111.000000
The five entered numbers were:
34.000000
-999.000000
56.000000
89.000000
111.000000
(a) Интересно, что это выглядит так происходит только с реальным пользовательским вводом, а не с передачей данных через программу в соответствии с моим оператором printf
.
Поведение идеально , по моему мнению, должно было бы оставить поток ввода, указывающий на неверные данные. Другими словами, если точный текст не является допустимым (например, nan
), указатель не должен двигаться вообще. Однако в стандарте C есть сноска, которая допускает такое поведение, если, например, входной поток недоступен для поиска:
fscanf
возвращает максимум один входной символ на входной поток.
Таким образом, хотя он может быть в состоянии выполнить резервное копирование дальше, чем на конвейере, это может быть не так при работе с терминалом input.
Когда я ввожу x
в качестве ввода, кажется, что делает pu sh, что обратно, потому что каждый последующий элемент массива заполнен 3
, что означает, что он читает что x
непрерывно. Все, что начинается с n
, похоже, потребляет только этот и следующий символ.