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
std::stringobjects 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.