0

这是我的代码:

#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 号处停止。

最后一辆车也打印了两次!!!

4

1 回答 1

2

我对你有问题并不感到惊讶!您从字面上保存结构的字节,然后当您从文件中读回它们时,您希望再次获得 std::string 。它根本不起作用。

问题是 car 结构不包含它引用的所有数据:std::string 成员实际上只是指向包含实际字符串数据的动态数组的指针。您将汽车结构写为原始字节,因此字符串永远不会归档。不可能从其中读出它们。

更糟糕的是,当您重新读取结构时,您将 std::string 中的指针设置为垃圾值。你不可能希望他们碰巧指向的内存包含你想要的东西。

您需要为 car 结构定义序列化函数,使用深层副本将其发送到外流,然后安全地读回。永远不要将原始指针值写入文件。

示例代码

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*作为一个很好的一般规则,在您了解它的作用以及字符串的处理方式之前,永远不要强制转换!

于 2012-12-10T19:08:51.960 回答