Код, использующий find = strchr(s, '\n')
и последующие, закрывает новую строку, прочитанную fgets()
и включенную в строку результата, если в строке действительно есть новая строка.Часто вы можете использовать альтернативную, более компактную запись:
s[strcspn(s, "\n")] = '\0';
, написанную без видимого условного кода.(Если нет новой строки, нулевой байт перезаписывает существующий нулевой байт.)
Общая цель, по-видимому, состоит в том, чтобы заставить s_gets()
вести себя как античная, опасная и более не стандартная функция, gets()
, который читает до и включая перевод строки, но не включает перевод строки в результат.Функция gets()
имеет и другие недостатки дизайна, которые делают ее функцией, которую нужно забыть - никогда не используйте ее!
Показанный код также обнаруживает, когда не было прочитано ни одной новой строки, а затем переходит в опасный цикл для чтения остальной частилиния.Цикл должен быть:
else
{
int c;
while ((c = getchar()) != EOF && c != '\n')
;
}
Важно обнаружить EOF;не все файлы заканчиваются символом новой строки.Также важно надежно обнаруживать EOF, что означает, что этот код должен использовать int c
(тогда как исходный некорректный цикл мог бы избежать использования такой переменной, как c
).Если этот код небрежно использовал char c
вместо int c
, он может либо вообще не обнаружить EOF (если обычный char
тип без знака), либо дать ложное срабатывание для EOF, когда читаемые данные содержат байтсо значением 0xFF (если обычный char
является типом со знаком).
Обратите внимание, что использование strcspn()
напрямую, как показано, не является вариантом в этом коде, потому что тогда вы не сможете определить, была ли новая строка вданные;Вы просто знаете, что в данных после вызова нет новой строки.Поскольку Антти Хаапала указывает на , вы можете зафиксировать результат strcspn()
и затем решить, был ли найден символ новой строки и, следовательно, следует ли читать до конца строки (или до конца файла).если нет EOL до EOF).