Это объясняется простой ссылкой на man scanf
. В первом случае:
scanf ("%19s",str);
Спецификатор преобразования %s
игнорирует начальные пробелы, поэтому '\n'
, оставшийся во входном буфере (stdin
), используется незаметно.
В вашемвторой случай:
scanf ("name=%19s",str);
Вы строка формата ищет литерал "name="
в качестве части ввода, который, так как '\n'
, оставшийся после вашего предыдущего ввода, не используется, ошибка совпадения происходит потому, что на самом деле ваш ввод "\nname=..."
, извлечение символов прекращается в этой точке, оставляя символы во входном буфере непрочитанными, что приводит к одному и тому же сбою при каждом последующем вводе.
Вы можете решить эту проблему, включая пустое пространство в начале строки формата , в результате чего любой начальный пробел будет использоваться с:
scanf (" name=%19s",str);
Теперь вы можете ввести, например:
name=Gary
name=Tom
...
(конечно, у вас все еще будет проблема посторонних символов, если пользователь введет более 19 символов для любого имени - или если кошка случайно наступит на клавиатуре)
Вы также должны проверить возврат КАЖДОЙ используемой функции ввода - особенно scanf
. Просто убедитесь, что число ожидаемых конверсий имеет место, например,
if (scanf (" name=%19s",str) != 1) {
fputs ("error: conversion failed.\n", stderr);
/* handle error */
}