This is my code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
struct car
{
string name, model;
int year;
};
void search_car(int CarYear)
{
cout<<"1";
ifstream in;
cout<<"2";
car c1;
cout<<"3";
in.open("Cars.txt",ios::binary|ios::in);
cout<<"4"<<endl;
while(!in.eof())
{
cout<<" 5";
in.read((char *) &c1, sizeof(car));
cout<<" 6.Car Year: "<<c1.year<<endl;
if(c1.year == CarYear)
{
cout<<" 7>>> ";
cout<<c1.name<<" "<<c1.model<<" "<<c1.year;
cout<<" <<<8"<<endl;
}
}
cout<<" 9";
in.close();
cout<<" 10";
}
void main()
{
car c[100];
int carNum, menuAct = 0, CarYear = -1, cycle = 1;
ofstream out;
while (cycle == 1)
{
//clrscr();
cout<<endl<<endl<<"1.Enter New car"<<endl<<"2.Search"<<endl<<"3.Exit"<<endl;
cin>>menuAct;
cout<<" Menu Action: "<<menuAct<<endl;
if(menuAct == 1)
{
cout<<"Enter Num OF Cars: ";
cin>>carNum;
out.open("Cars.txt",ios::binary|ios::out|ios::app);
for(int i = 0; i < carNum; i++)
{
cout<<"Enter Name OF Car: ";
cin>>c[i].name;
cout<<"Enter model OF Car: ";
cin>>c[i].model;
cout<<"Enter year OF Car: ";
cin>>c[i].year;
out.write((char *) &c[i], sizeof(car));
}
out.close();
}
else if(menuAct == 2)
{
cout<<"Enter Car Year: ";
cin>>CarYear;
cout<<" 0";
//cout<<" Y: "<<CarYear;
search_car(CarYear);
cout<<" 11";
//menuAct = 0;
}
else if(menuAct == 3)
{
cycle = 0;
}
}
}
Error:
http://s3.picofile.com/file/7580464836/cpp_err11.jpg
What is happened?
I`m used some cout to trace what is happening and code is stopped at number 10.
Also last car is printed twice!!!
I’m not surprised you’re having problems! You’re saving the bytes of the struct literally, and then when you read them back from the file, you’re hoping you’ll get a std::string back again. It doesn’t work that way at all.
The problem is that the car struct doesn’t contain all the data it references: the std::string members are actually just pointers to a dynamic array containing the actual string data. You’re writing out the car structures as raw bytes, so the strings are never going to file. There’s no way they could ever be read back out of it.
Worse, when you read the structs back in, you’re setting the pointers in the std::string to garbage values. You can’t possibly hope that the memory they happen to point to contains what you want.
You need to define serialisation functions for the car struct, that send it to an outstream using a deep copy, and read it back in safely. Never write raw pointer values to file.
Example code
Change
in.read((char *) &c1, sizeof(car));toin >> c1;.Change
out.write((char *) &c[i], sizeof(car));toout << c[i];.Much neater! PS. As an excellent general rule, don’t ever cast to
char*until you understand what it does and how strings are handled!