Exeption thrown binary file C++

64 Views Asked by At

EDIT: Based on suggestion of Retired Ninja, I serialized the data when writing and reading resulting into another two functions

void writeString(std::fstream& file, const std::string& str)
{
    // Write the length of the string first
    size_t length = str.size();
    file.write(reinterpret_cast<const char*>(&length), sizeof(size_t));

    // Write the characters of the string
    file.write(str.c_str(), length);
}

std::string readString(std::fstream& file)
{
    // Read the length of the string first
    size_t length;
    file.read(reinterpret_cast<char*>(&length), sizeof(size_t));

    // Resize the string and read the characters
    std::string str(length, '\0');
    file.read(&str[0], length);

    return str;
}

and changed the way of writing and reading using these functions

for (int i = 0; i < n; ++i) {
    file.write(reinterpret_cast<const char*>(&cookiesInput[i].no_of_pieces), sizeof(int));
    file.write(reinterpret_cast<const char*>(&cookiesInput[i].price), sizeof(float));
    writeString(file, cookiesInput[i].name);
}
    
std::vector<Cookie>cookiesOutput(n);
for (int i = 0; i < n; ++i) {
    file.read(reinterpret_cast<char*>(&cookiesOutput[i].no_of_pieces), sizeof(int));
    file.read(reinterpret_cast<char*>(&cookiesOutput[i].price), sizeof(float));
    cookiesOutput[i].name = readString(file);
}

In the code snipped below I am trying to read read n numbers of structures Cookies and store them in a vector so to write the data into a binary file afterwards. I am validating the input of n to be an integer and the name of the file in which I am writing is also read from keyboard. I am using a fstream object to both read and write a binary file(I am using std::ios::app as without this it returns that the file can't be opened when check if file could be opened).

The problem is that I get Exception thrown: read access violation. **_Pnext** was 0xFFFFFFFFFFFFFFFF. just after I close the file, even if the bubble sort does its work and print correct result.

I checked the vector in watch window to see if the data is correct written and read and seems to be ok. I also tried to write with a ofstream object the binary file and read it with an ifstream object but same exeption. If I use file only for writing and I use the cookieInput for sorting will work, but the scope of the program is to be able to read and write from binary file.

#include <iostream> 
#include <fstream> 
#include <limits> 
#include <string> 
#include <vector> 

struct Cookie
{
    std::string name;
    int no_of_pieces=0;
    float price=0;
};

// Function to perform bubble sort on the vector of cookies 
void bubbleSort(std::vector<Cookie>& cookies);

int main() {
    int n; // number of cookie boxes 

    // Prompt the user for the number of cookie boxes 
    std::cout << "Enter the number of cookie boxes: ";

    // Validate and handle user input for n 
    while (!(std::cin >> n) || std::cin.fail() || std::cin.peek() != '\n' || n < 1) {

        // Clear the error state of the input stream 
        std::cin.clear();

        // Clear  the input buffer 
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        std::cerr <<"The input is invalid. Enter an integer number greater than zero";
    }

    std::vector<Cookie> cookiesInput(n);
    for (int i = 0; i < n; ++i) {
        // Prompt user for the name of each box of cookies 
        std::cout << "Enter the name of the box " << i + 1 << " of cookies: ";
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

        std::getline(std::cin, cookiesInput[i].name);

        // Prompt user for the number of pieces in each box of cookies 
        std::cout << "Enter the number of pieces in the box " << i + 1 <<
            " of cookies: ";
        std::cin >> cookiesInput[i].no_of_pieces;

        // Prompt user for the price of each box of cookies 
        std::cout << "Enter the price of the box " << i + 1 << " of cookies: ";
        std::cin >> cookiesInput[i].price;
    }

    // Clear the input buffer 
    std::cin.ignore();

    // Prompt the user for the binary file's name 
    std::cout << "Enter the name of the binary file: ";

    std::string filename;
    std::getline(std::cin, filename);

    // Open the binary file in binary read-write with append mode 
    std::fstream file(filename, std::ios::binary | std::ios::in | std::ios::out | std::ios::app);

    // Check if the file was successfully opened 
    if (!file.is_open()) {
        std::cerr << "Unable to open the file\n";
        return 1;
    }

    // Write cookiesInput vector to the binary file 
    for (int i = 0; i < n; ++i) {
        file.write(reinterpret_cast<const char*>(&cookiesInput[i]), sizeof(Cookie));
    }
    
    // Reset the file position to the beggining 
    file.seekg(0, std::ios::beg);

    // Check if the file is open before proceeding with reading 
    if (!file.is_open()) {
        std::cerr << "Error reading from the file\n";
        return 1;
    }

    // Read cookiesOutput vector from the binary file 
    std::vector<Cookie>cookiesOutput(n);
    for (int i = 0; i < n; ++i) {
        file.read(reinterpret_cast<char*>(&cookiesOutput[i]), sizeof(Cookie));
    }

    
    // Sort the cookiesOutput vector using bubbleSort 
    bubbleSort(cookiesOutput);

    // Display information about the cheapest box of cookies 
    std::cout << "The name of the cheapest box of cookies is: " <<
        cookiesOutput[0].name << std::endl;
    std::cout << "The number of pieces of the cheapest box of cookies is: " <<
        cookiesOutput[0].no_of_pieces << std::endl;
    std::cout << "The price of the cheapest box of cookies is: " <<
        cookiesOutput[0].price << std::endl;

    // Close the binary file 
    file.close();

    return 0;
}//main
0

There are 0 best solutions below