这是我的代码:
#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;
}
}
}
错误:
http://s3.picofile.com/file/7580464836/cpp_err11.jpg
发生了什么事? 我用了一些cout来追踪发生了什么,代码在10号停止了。
最后一辆车也打印了两次!!!
答案 0 :(得分:2)
我对你遇到问题并不感到惊讶!你从字面上保存结构的字节,然后当你从文件中读回它们时,你希望你再次得到一个std :: string。它根本不起作用。
问题是car结构不包含它引用的所有数据:std :: string成员实际上只是指向包含实际字符串数据的动态数组的指针。您将汽车结构写为原始字节,因此字符串永远不会归档。他们无法从中读回来。
更糟糕的是,当您重新读取结构时,您将std :: string中的指针设置为垃圾值。你不可能希望他们碰巧指出的记忆包含你想要的东西。
您需要为car结构定义序列化函数,使用深层副本将其发送到outstream,并安全地将其读回。切勿将原始指针值写入文件。
ostream& operator <<(ostream& os, const car& c) {
return os << c.name << endl << c.model << endl << c.year << endl;
}
istream& operator >>(istream& is, car& c) {
is >> c.name;
is >> c.model;
is >> c.year;
return is;
}
将in.read((char *) &c1, sizeof(car));
更改为in >> c1;
。
将out.write((char *) &c[i], sizeof(car));
更改为out << c[i];
。
更整洁! PS。作为一个很好的一般规则,在你理解它的作用以及如何处理字符串之前,不要强制转换为char*
。