Search code examples
c++overflowfstreamchaining

working with fstream files in overflow chaining in c++


I have a file that I want to read and write to a binary file using records. In the beginning I have an empty file and I want to add new record, but when I use the seekp function, then the location is at (-1) is it ok? Because when I check, I see that it hasnt written anything to the file. See code:

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++;
        }
    }

If anyone can tell me why I cant write anything to the file I will really appriciate it.

Thanks in advance,

Greg


Solution

  • Well here are a few suggestions that may help:

    • when you open the file, use ios_base::binary flag
    • make sure that Book is a POD (i.e. a C compatible type)
    • make sure that when you read or write that the stream is in a valid state before and after
    • don't use readBook.getId() == -1 to check if the read succeeded
    • make sure that when you seek into the stream you're not going past the end of file
    • use the buffer to get the total number of bytes in the file and then ensure that you don't exceed it before seeking
    • whenever you seek, do a relative seek (use ios_base::beg for e.g)
    • use static_cast<char*>(static_cast<void*>(&book)) vs reinterpret cast<char*>

    If you have any specific questions about any of those suggestions, let us know and perhaps we can guide you better.