Дополнительные s
после %[^\n]
- распространенная ошибка.Это может произойти из-за путаницы между наборами сканирования и спецификатором преобразования %s
.
Его эффект в строке формата scanf
соответствует совпадению байта s
во входном потоке.Такое совпадение всегда будет неудачным, потому что после успешного преобразования спецификатора %[^\n]
поток находится либо в конце файла, либо ожидающий символ является новой строкой.Если в строке формата отсутствуют дополнительные спецификаторы преобразования, этот сбой не повлияет на возвращаемое значение scanf()
, поэтому эта ошибка редко возникает.
Обратите также внимание на следующие предостережения:
- спецификатор
%[^\n]
завершится с ошибкой в пустой строке. - безопаснее всегда указывать максимальное количество байтов для преобразования для спецификаторов
%[]
и %s
, чтобы избежать неожиданного неопределенного поведениябольшие вводы. scanf("%99[^\n]", line)
оставит перевод строки в ожидании во входном потоке, вы должны использовать его, прежде чем сможете прочитать следующую строку с той же строкой формата scanf
.
В отличие от while (fgets(line, sizeof line, stdin)) { ... }
, вы не можете просто написать while (scanf("%99[^\n]", line) == 1) { ... }
для чтения всего файла построчно, вы должны использовать ожидающую новую строку в теле цикла, и цикл остановится на первой пустой строке.
Пример:
char line[100];
if (scanf("%99[^\n]", line) == 1) {
/* handle input line */
} else {
/* stream is at end of file or has an empty line */
}