Ваш цикл имеет несколько проблем. Вы написали:
while( fscanf( f, "%[^\n\r]s", cLine ) != EOF )
/* do something */;
Некоторые вещи, которые следует учитывать:
fscanf () возвращает количество сохраненных элементов. Он может вернуть EOF, если он читает после конца файла или если дескриптор файла имеет ошибку. Необходимо отличить действительный возврат от нуля, в этом случае в буфере cLine
нет нового содержимого от успешно прочитанного.
У вас есть проблема, когда происходит сбой сопоставления, потому что трудно предсказать, где указатель файла теперь указывает в потоке. Это делает восстановление после неудачного матча труднее, чем можно было бы ожидать.
Шаблон, который вы написали, вероятно, не выполняет то, что вы хотели. Он соответствует любому количеству символов, которые не являются CR или LF, и затем ожидает найти литерал s
.
Вы не защитили свой буфер от переполнения. Любое количество символов может быть прочитано из файла и записано в буфер, независимо от размера, выделенного этому буферу. К сожалению, это распространенная ошибка, которая во многих случаях может быть использована злоумышленником для запуска произвольного кода, выбранного злоумышленниками.
Если вы специально не запросили, чтобы f
был открыт в двоичном режиме, в библиотеке произойдет перевод конца строки, и вы, как правило, никогда не увидите символы CR, обычно не в текстовых файлах.
Вы, вероятно, хотите цикл, похожий на следующий:
while(fgets(cLine, N_CLINE, f)) {
/* do something */ ;
}
где N_CLINE - количество байтов, доступных в буфере, начиная с cLine
.
Функция fgets()
является наиболее предпочтительным способом чтения строки из файла. Его вторым параметром является размер буфера, и он считывает до 1 байта этого размера из файла в буфер. Он всегда завершает буфер символом nul
, чтобы его можно было безопасно передать другим строковым функциям C.
Останавливается на первом из конца файла, чтения новой строки или buffer_size-1
байтов.
Он оставляет символ новой строки в буфере, и этот факт позволяет вам отличить одну строку длиннее вашего буфера от строки, короче буфера.
Возвращает NULL, если байты не были скопированы из-за конца файла или ошибки, и указатель на буфер в противном случае. Возможно, вы захотите использовать feof()
и / или ferror()
для различения этих случаев.