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

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

Примечание:

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

4 ответов


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

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

char buffer[4096];

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

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

  1. обрабатывайте слишком длинные строки в битах, не предполагая, что между ними есть новая строка.
  2. выделите память для более длинной строки (скажем, 8K для начала), скопируйте начальный 4K в выделенный буфер и прочитайте больше данных во вторую половину буфера, повторяя, пока не найдете конец строки.
  3. используйте функцию POSIX 2008 getline() который доступен в Linux. Он делает выделение памяти для вас.

вы можете использовать fgets итеративно, но более простой альтернативой является (stdio.х) getline. Это в POSIX, но это не стандартный C.

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


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


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

что-то типа:

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

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

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