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番で停止します。

また、最後の車は2回印刷されます!!!

4

1 に答える 1

2

あなたが問題を抱えているのは驚きではありません!構造体のバイトを文字通り保存していて、ファイルからそれらを読み戻すときに、std::stringが再び返されることを期待しています。それはまったくそのようには機能しません。

問題は、car構造体に、それが参照するすべてのデータが含まれていないことです。std:: stringメンバーは、実際には、実際の文字列データを含む動的配列への単なるポインターです。車の構造を生のバイトとして書き出すので、文字列がファイルされることはありません。彼らがそれから読み戻すことができる方法はありません。

さらに悪いことに、構造体を読み戻すと、std::stringのポインタがガベージ値に設定されていることになります。彼らがたまたま指し示している記憶にあなたが望むものが含まれていることを期待することはできません。

カー構造体のシリアル化関数を定義する必要があります。これは、ディープコピーを使用してアウトストリームに送信し、安全に読み戻す必要があります。生のポインタ値をファイルに書き込まないでください。

サンプルコード

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 に答える