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