Я хочу читать в файле линию за линией, не зная длины строки прежде. Вот то, что я получил до сих пор:
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
Вы можете начать с подходящего размера по вашему выбору, а затем использовать 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
.
Вы близко.Обычно вы хотите читать фрагменты данных и проверять их на наличие \ n
символов. Если вы его найдете, хорошо, у вас конец. Если вы этого не сделаете, вам придется увеличить свой буфер (т.е. выделить новый буфер в два раза больше размера первого и скопировать данные из первого в новый, затем удалить старый буфер и переименовать новый буфер как old - или просто realloc
, если вы в C), затем читайте еще, пока не найдете концовку.
Когда у вас есть окончание, текст от начала буфера до символа \ n
будет вашей строкой. Скопируйте его в буфер или работайте с ним на месте, на ваше усмотрение.
После того, как вы будете готовы к следующей строке, вы можете скопировать «остаток» ввода в текущую строку (в основном сдвиг влево) и заполнить оставшуюся часть буфера данными из ввода. Затем вы идете снова, пока у вас не закончатся данные.
Это, конечно, можно оптимизировать, например, с помощью кольцевого буфера, но этого должно быть более чем достаточно для любого разумного алгоритма с ограничением io.
Вы можете изучить общественное достояние Чака Б. Фалконера ggets
библиотеку . Если вы работаете в системе с glibc, вам, вероятно, доступна (нестандартная) функция getline
.