Спецификатор "%s"
в scanf("%s", nameInput);
сначала потребляет 1 и отбрасывает первые пробелы, включая все '\n'
из Введите перед сканированием и сохранением в nameInput
.
Именно поэтому повторные записи пустых строк не продвигают сканирование. "%s"
ожидает некоторого ввода без пробелов.
Лучшей альтернативой scanf()
является чтение всего пользовательского ввода с помощью fgets()
, а затем анализ строки .
fgets()
читает строку и сохраняет результат в виде строки - обычно включая окончание строки '\n'
.
// scanf("%s", nameInput);
if (fgets(nameInput, sizeof nameInput, stdin)) {
// Success at reading input.
nameInput[strcspn(nameInput, "\n")] = '\0'; // lop off the potential trailing \n
if(!strcmp(nameInput, "")){ // or simply `if(nameInput[0] == '\0')
break;
}
...
также пытались сравнить с \ 0, но безрезультатно.
if(!strcmp(nameInput, ""))
и if(!strcmp(nameInput, "\0"))
делают то же самое. strcmp()
сравнивает строк .
""
- строковый литерал из 1 char
: нулевой символ .
"\0"
- строковый литерал из 2 char
: два нулевых символа .
строка сравнение останавливается на первом нулевом символе .
"%s"
само по себе также не имеет ограничения по ширине. Код не имеет надежной защиты от ввода типа «BlahBlah ... (120_some_more) Blah») и может привести к неопределенному поведению из-за переполнения буфера char nameInput[128];
. Код мог бы использовать "%127s"
, чтобы предотвратить это, но он обрабатывает только один из недостатков scanf()
.
1
Пропущенные символы пробела (как определено функцией isspace
) пропускаются, если в спецификации не указано * 1078 Спецификатор *, c
или n
. C17dr § 7.21.6.2 8