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

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

Примечание:

char *fgets(char *str, size_t num, FILE *stream);

person vette982    schedule 21.05.2010    source источник
comment
Ваш заголовок предполагает, что вы хотите использовать fgets, но текст подразумевает, что вы ищете альтернативы. Что заставило вас пойти на fgets в первую очередь ..?   -  person Default    schedule 21.05.2010


Ответы (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. Он делает распределение памяти для вас.
person Jonathan Leffler    schedule 21.05.2010


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

person jamesdlin    schedule 21.05.2010

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

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

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

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

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

person danben    schedule 21.05.2010
comment
Как это? Если вы не перераспределите буфер, любое дополнительное пространство все еще будет использоваться. - person Matthew Flaschen; 21.05.2010
comment
Я имею в виду место в буфере, а не место в памяти. Кроме того, вопрос ОП был не о том, как сохранить память. - person danben; 21.05.2010