Хранить каждую строку файла как строку в массиве - PullRequest
0 голосов
/ 24 сентября 2019

У меня есть файл, который выглядит следующим образом:

Tom
John
Sarah
...

Мне нужно прочитать этот файл и сохранить каждое имя в массиве.Количество строк неизвестно и может варьироваться.Символ новой строки будет \n Я предполагаю (конечно, это не видно в файле).

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

Это то, чтоУ меня так далеко:

#define BUFFSIZE        4096

int main( int argc, const char* argv[] )
{
        int n;
        char buf[BUFFSIZE];

        // Throw error if not exactly 2 arguments
        if(argc != 2) {
                printf("Usage: %s <file_name>\n", argv[0]);
                exit(-1);
        }

        // open file and check if error thrown
        int readFileDescriptor = open(argv[1], O_RDONLY);
        if (readFileDescriptor == -1) {
                printf("Error with file open\n");
                exit (-1);
        }

        // Read until end of file was reached
        while((n = read(readFileDescriptor, buf, BUFFSIZE)) > 0) {
                // ... do something here
        }
        if(n < 0) {
                printf("Read error\n");
        }

        close(readFileDescriptor);
        return(0);
}

Во-первых, я не уверен, как преодолеть проблему, если имя обрезается посередине из-за буфера.Во-вторых, как разделить на символ /n и поместить каждое имя в массив.Для массива мне сказали использовать динамический массив с malloc и realloc, чтобы изменить его размеры.

Заранее большое спасибо!Я застрял с этим уже некоторое время и не знаю, где продолжить.

Ответы [ 2 ]

1 голос
/ 24 сентября 2019

Используйте следующий алгоритм:

  1. Заполните буфер.
  2. Проверьте буфер на наличие первого символа новой строки.
  3. Если символа новой строки нет, остановите, все готово.
  4. Выделите новый буфер размером с запись, конец которой вы только что нашли.
  5. Скопируйте запись, конец которой вы нашли на шаге 2, в буфер.
  6. Переместите любые символы, оставшиеся в буфере, в начало буфера.
  7. Перейдите к шагу 1.

Это не особенно эффективно, но оно выполнит свою работу.

0 голосов
/ 24 сентября 2019

Возможные альтернативы:

a) Когда вы удаляете что-либо из буфера (например, от начала буфера до середины), сдвигайте любые оставшиеся данные (например, сдвигайте данные из середины в конец обратно).в начало), а затем снова заполните буфер (от нового середины до конца).Примечание: это не может работать, если одна строка текста может быть больше, чем буфер.

b1) Сделать буфер больше, чем файл.Таким образом, вы можете просто заменить символы новой строки символами конца строки (и, возможно, отбросить любой «пробел в конце строки» и пропустить пустые строки и т. Д.);и избегайте целой кучи "malloc() накладных расходов", потому что вам не нужно выделять память для каждой отдельной строки (потому что вы повторно используете память, которую вы уже выделили).Примечание: это не может работать, если файл может быть больше доступной виртуальной памяти.

b2) Используйте mmap(), чтобы отобразить файл в памяти;затем замените символы новой строки символами конца строки и т. д. Примечание. Это не может работать, если файл может быть больше доступной виртуальной памяти.

c1) Прекратить использовать ужасные форматы файлов в виде простого текста и просто хранить строки (с ограничителями строки и без символов новой строки) в файле для начала.Это позволяет вам mmap() без изменения памяти после.Примечание: это не может работать, если файл может быть больше доступной виртуальной памяти.

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

Если данные файла уже кэшированы в ОЗУ операционной системой;«option c2)» может быть в 1000 раз быстрее, чем «option a)».

e) Объединить «опция b2)» с «опция c2)».Когда ваша программа запускается, сравните метки времени для «input.txt» и «input.bin», а если «input.txt» новее, используйте «option b2)», сгенерируйте индекс и сохраните его как «input.bin» дляв следующий раз;в противном случае (если «input.bin» новее), используйте «option c2)».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...