0

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
10
  • 1
    Which line does the debugger stop at declaring a read access violation ? Commented Jan 22, 2024 at 8:24
  • What is a debugger and how can it help me diagnose problems? Commented Jan 22, 2024 at 8:29
  • You can't write std::string objects to disk and then read them back. The string object doesn't contain any data, it is just a few pointers. You need to properly serialize the data. One way is to write the length and then the data then to read it back you read the length, resize the destination string, and read the data. Commented Jan 22, 2024 at 8:30
  • 2
    You cannot write C++ objects to file and then read them back like this. Casting a memory block to an object will NOT call its constructor and you will not end up with valid objects. What you need is called (binary) serialization and it is NOT a trivial thing to do right (considering different compilers and or compiler settings may result in different layouts in memory). Really you should use a serialization library to do this for you Commented Jan 22, 2024 at 8:33
  • @AhmedAEK file.close() line Commented Jan 22, 2024 at 8:35

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.