Как использовать fgets, если Вы не знаете, что количество символов читается?

Я должен считать файл и отправить текст от него до строки, таким образом, я могу проанализировать его. Однако программа не будет знать точно, какой длины файл, поэтому что я сделал бы, если бы я хотел использовать fgets(), или есть ли лучшая альтернатива?

Примечание:

char *fgets(char *str, size_t num, FILE *stream);
8
задан gsamaras 14 May 2015 в 13:28
поделиться

4 ответа

Не забывайте, что fgets () читает строку за раз, при условии наличия достаточного места.

Люди редко пишут строки длиннее ... 80, 256, выбирайте число ... символов. POSIX предлагает длину строки 4096. Итак, я обычно использую:

char buffer[4096];

while (fgets(buffer, sizeof(buffer), fp)) 
{
    ...process line...
}

Если вы обеспокоены тем, что кто-то может предоставить более 4 КБ данных в одной строке (а файл, сгенерированный машиной, такой как HTML или JSON, может содержать это ), то вам нужно решить, что делать дальше. Вы можете сделать любое из следующего (и, вероятно, есть некоторые другие варианты, которые я не упомянул):

  1. Обработать слишком длинные строки в битах, не предполагая, что между ними есть новая строка.
  2. Выделите память для более длинной строки (скажем, 8 КБ для начала), скопируйте начальный 4 КБ в выделенный буфер и считайте больше данных во вторую половину буфера, повторяя до тех пор, пока не найдете конец строки.
  3. Используйте функцию POSIX 2008 getline () , которая доступна в Linux. Он выделяет память за вас.
10
ответ дан 5 December 2019 в 10:39
поделиться

Вы можете использовать fget итеративно, но более простой альтернативой является (stdio.h's) getline . Он входит в POSIX, но не является стандартным C.

Поскольку вы используете C ++, можете ли вы использовать функции std :: string, такие как iostream getline ?

3
ответ дан 5 December 2019 в 10:39
поделиться

Если вы не используете систему POSIX и у вас нет доступной getline , взгляните на общественное достояние Чака Фалконера ggets ] / fggets функции , которые динамически увеличивают буфер для использования всей строки. (Эта ссылка сейчас недоступна, но на archive.org есть копия .)

3
ответ дан 5 December 2019 в 10:39
поделиться

Выделите буфер (тот, на который указывает str), и передайте размер буфера для num. Фактически занимаемое пространство будет равно только длине текста, считываемого fgets.

Что-то вроде:

char str[1000];
fgets(str, 1000, &file);

Если следующая строка содержит только 10 символов до новой строки, то str будет содержать эти 10 символов, новую строку и нулевой терминатор.

Edit: на всякий случай, если возникнет путаница, я не хотел сказать, что дополнительное пространство в буфере не используется. Я лишь хотел показать, что вам не нужно знать заранее, какой длины будет ваша строка, если вы можете задать ее максимальную длину.

0
ответ дан 5 December 2019 в 10:39
поделиться