открыть и синхронизировать с диском - PullRequest
0 голосов
/ 25 декабря 2011

Я написал программу, которая должна записывать структуру в двоичный файл и читать из нее. Я использую fread, fwrite, fopen, fseek и fclose. Я написал следующую функцию, которая печатает все записи в моем файле.

void ReadFile::printList(){
//  clearerr(bookFilePtr);

    fseek(bookFilePtr,0L,SEEK_SET); // set to begin of file

    int counter = 1;
    long int line = 1;
    int pageCounter = 1;

    while (this->readFromFile() == 1){
        string output;
        mvprintw(++line, 27,"***Title*****************Value*********" );
        output = "Name:               " + bookPtrObj->name;
        mvprintw(++line, 27, output.data());
        output = "Publisher:          " + bookPtrObj->publisher;
        mvprintw(++line, 27,output.data());
        output = "Author:             " + bookPtrObj->author;
        mvprintw(++line, 27,output.data());
        output = "Translator:         " + bookPtrObj->translator;
        if (bookPtrObj->translation == true )
            mvprintw(++line, 27,output.data());
        if (bookPtrObj->stock != true )
            mvprintw(++line, 27,"Stock:              The given book doesn't exist.");
        else
            mvprintw(++line, 27,"Stock:              The given book exist.");
        if ( pageCounter % 3 == 0){
            mvprintw(++line, 27,"Press any key to see next page...");
            getch();
            clear();
            line = 1;

        }
        pageCounter++;
        refresh();
        fseek(bookFilePtr, counter * sizeof(struct book) ,SEEK_SET); // seek to next data
        counter ++;
    }
//  fflush(bookFilePtr);

    menu();
}

Примечание: Я запускаю для первого ввода и ввода данных, я вижу свои данные сверху очень хорошо func и страницу на страницу. Но когда я выхожу из программы, все не работает. Когда я запускаюсь во второй раз и запустить выше функции, я получаю Ошибка сегментации , я отслеживаю это, bookPtrObj, что это указатель моей структуры, не могу прочитать мой файл. Я пытаюсь с типом fopen, [рб. wb, ab +, rb +, a +, w +, aw +] и так далее. но я не получил результат. Я пишу в файл со следующими строками. Конечно, я заполняю элемент struct и затем запускаю 2 следующие строки:

fseek(bookFilePtr,0L,SEEK_END);
fwrite(ptr,sizeof(struct book),1,bookFilePtr);

Как мне сохранить мои данные в файле?

Ответы [ 2 ]

2 голосов
/ 25 декабря 2011

Вы не предоставили много кода, но я предполагаю, что вы сохраняете указатели на строки, а не на сами строки, или даже хуже (или это хуже?) - std::string содержимое объекта.Вместо этого вам нужно правильно их сериализовать.

0 голосов
/ 25 декабря 2011

Прежде чем пытаться записать данные в файл или прочитать данные из файла, вы должны выписать спецификацию для формата, который будут иметь данные в файле.То, что вы делаете, это записывает произвольные байты данных в неизвестном формате в файл.Если это на самом деле работает, то это просто удача.

Если вы хотите сохранить, скажем, целое число, в файле, вам нужно решить, будете ли вы использовать фиксированную или переменную длину.Если переменная, как читатель определит, сколько байтов он занимает?Будут ли наиболее значимые цифры / биты первыми или наименее значимыми?Вы напишите это в текстовом или двоичном виде?

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

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

Вы не можете сделать это:

fwrite(ptr,sizeof(struct book),1,bookFilePtr);

Вы просто пишете произвольные байты вфайл.Да, они имеют смысл в вашем текущем контексте выполнения, но они могут иметь или не иметь смысл в другом контексте выполнения.Вам необходимо преобразовать их в четко определенный, автономный формат данных, подходящий для записи в файл.

Вот глупый пример:

const char *foo="foo";
fwrite(&foo, sizeof(&foo), 1, filePtr);

Это запишет содержимоеfoo, который является указателем на строку со значением "foo".Но когда вы читаете это обратно, вы читаете назад указатель на адресное пространство, которое больше даже не существует.Какой смысл в этом?Скорее всего, это не будет указывать на что-то значимое в вашем адресном пространстве.

...