У вашего цикла есть несколько проблем. Вы написали:
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()
, чтобы различать эти случаи.
person
RBerteig
schedule
14.05.2009