работа с файлами Fstream в цепочке переполнения в C ++ - PullRequest
1 голос
/ 14 июня 2009

У меня есть файл, который я хочу прочитать и записать в двоичный файл, используя записи. В начале у меня есть пустой файл, и я хочу добавить новую запись, но когда я использую функцию seekp, то местоположение находится в (-1), это нормально? Потому что, когда я проверяю, я вижу, что он ничего не записал в файл. Смотрите код:

void Library::addBook(Book newBook)
{
fstream dataFile;
dataFile.open("BookData.dat", ios::in | ios::out);
    if (!dataFile)
    {
        cerr << "File could not be opened" << endl;
    }

int hashResult = newBook.getId() % 4 + 1; // The result of the hash function

    // Find the right place to place the new book
    dataFile.seekg((hashResult - 1) * sizeof(Book), ios::beg);

    Book readBook;
    dataFile.read(reinterpret_cast<char*>(&readBook), sizeof(Book));

    // The record doesnt exist or it has been deleted
    if (readBook.getId() == -1)
    {
        // The record doesnt exist
        if (readBook.getIdPtr() == -1)
        {
            dataFile.seekp((hashResult - 1) * sizeof(Book));
            dataFile.write(reinterpret_cast<char*>(&newBook), sizeof(Book));

        }
        // The record has been deleted or there is already such record with such hash function
        // so we need to follow the pointer to the overflow file
        else
        {
            newBook.setIsBookInData(false); // New book is in overflow file
            overflowFile.seekg((readBook.getIdPtr() - 1) * sizeof(Book));
            overflowFile.read(reinterpret_cast<char*>(&readBook), sizeof(Book));
            // Follow the chain
            while (readBook.getIdPtr() != -1)
            {
                overflowFile.seekg((readBook.getIdPtr() - 1) * sizeof(Book));
                overflowFile.read(reinterpret_cast<char*>(&readBook), sizeof(Book));
            }
            readBook.setIdPtr(header); // Make the pointer to point to the new book
            overflowFile.seekp((header - 1) * sizeof(Book));
            overflowFile.write(reinterpret_cast<char*>(&newBook), sizeof(Book));
            header++;
        }
    }

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

Заранее спасибо,

Грег

Ответы [ 2 ]

2 голосов
/ 14 июня 2009

Ну вот несколько советов, которые могут помочь:

  • при открытии файла используйте ios_base :: binary flag
  • убедитесь, что Book - это POD (т.е. C-совместимый тип)
  • убедитесь, что при чтении или записи поток находится в допустимом состоянии до и после
  • не используйте readBook.getId () == -1 для проверки успешности чтения
  • убедитесь, что при поиске в потоке вы не выходите за конец файла
  • используйте буфер, чтобы получить общее количество байтов в файле, а затем убедитесь, что вы не превысили его, прежде чем искать
  • всякий раз, когда вы ищете, выполняйте относительный поиск (например, используйте ios_base :: beg для *)
  • использовать static_cast<char*>(static_cast<void*>(&book)) против reinterpret cast<char*>

Если у вас есть какие-либо конкретные вопросы по любому из этих предложений, сообщите нам, и, возможно, мы поможем вам лучше.

1 голос
/ 14 июня 2009

Вы, очевидно, читаете за концом файла. Ваш вызов seekg , вероятно, перемещает указатель чтения за конец, затем вы вызываете read . Это переведет ваш поток в состояние сбоя. Проверьте это, выполнив:

std::cout << dataFile.fail() << std::endl;

после read call.

Вид управления записями, который вы пытаетесь сделать, не является тривиальной задачей. Может быть, вам стоит попробовать DBE без сервера, например SQLite или другие библиотеки сериализации, например Boost.Serialization .

Кроме того, вы должны открыть файл с флагом ios :: binary .

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