Считайте строку из файла, не зная длины строки

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

int ch = getc(file);
int length = 0;
char buffer[4095];

while (ch != '\n' && ch != EOF) {
    ch = getc(file);
    buffer[length] = ch;
    length++;
}

printf("Line length: %d characters.", length);

char newbuffer[length + 1];

for (int i = 0; i < length; i++)
    newbuffer[i] = buffer[i];

newbuffer[length] = '\0';    // newbuffer now contains the line.

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

- Ry

27
задан ryyst 28 March 2010 в 09:37
поделиться

3 ответа

Вы можете начать с подходящего размера по вашему выбору, а затем использовать realloc на полпути, если вам нужно больше места, например:

int CUR_MAX = 4095;
char *buffer = (char*) malloc(sizeof(char) * CUR_MAX); // allocate buffer.
int length = 0;

while ( (ch != '\n') && (ch != EOF) ) {
    if(length ==CUR_MAX) { // time to expand ?
      CUR_MAX *= 2; // expand to double the current size of anything similar.
      buffer = realloc(buffer, CUR_MAX); // re allocate memory.
    }
    ch = getc(file); // read from stream.
    buffer[length] = ch; // stuff in buffer.
    length++;
}
.
.
free(buffer);

Вы Вам нужно будет проверить наличие ошибок распределения после вызовов malloc и realloc .

15
ответ дан 28 November 2019 в 05:50
поделиться

Вы близко.Обычно вы хотите читать фрагменты данных и проверять их на наличие \ n символов. Если вы его найдете, хорошо, у вас конец. Если вы этого не сделаете, вам придется увеличить свой буфер (т.е. выделить новый буфер в два раза больше размера первого и скопировать данные из первого в новый, затем удалить старый буфер и переименовать новый буфер как old - или просто realloc , если вы в C), затем читайте еще, пока не найдете концовку.

Когда у вас есть окончание, текст от начала буфера до символа \ n будет вашей строкой. Скопируйте его в буфер или работайте с ним на месте, на ваше усмотрение.

После того, как вы будете готовы к следующей строке, вы можете скопировать «остаток» ввода в текущую строку (в основном сдвиг влево) и заполнить оставшуюся часть буфера данными из ввода. Затем вы идете снова, пока у вас не закончатся данные.

Это, конечно, можно оптимизировать, например, с помощью кольцевого буфера, но этого должно быть более чем достаточно для любого разумного алгоритма с ограничением io.

1
ответ дан 28 November 2019 в 05:50
поделиться

Вы можете изучить общественное достояние Чака Б. Фалконера ggets библиотеку . Если вы работаете в системе с glibc, вам, вероятно, доступна (нестандартная) функция getline .

5
ответ дан 28 November 2019 в 05:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: