Probleme mit Dateien



  • Hallo liebe C++-ler,

    ich beschäftige mich gerade mit dem Speichern von Objekten in Dateien und habe dazu folgendes kleines Prohgramm geschrieben:
    [code]
    #include <iostream>
    #include <fstream>
    #include <conio.h>
    #include <string>
    using namespace std;
    /* run this program using the console pauser or add your own getch, system("pause") or input loop */
    class person
    {
    private:
    string name;
    int alter;

    public:
    void getdata()
    {
    cout<< "Name:";
    getline(cin,name);
    cout << "Alter";
    cin >> alter;
    fflush(stdin);
    }
    void showdata()
    {
    cout << name << " " << alter << endl;;
    }
    };
    int main(int argc, char *argv[])
    {
    person persfeld[3];
    person pers,pers2;
    fstream file;
    file.open("G:\\people.dat",ios::out|ios::trunc|ios::in|ios::binary);
    if(!file.good())
    cout<< "Fehler bei Dateihandling" << endl;

    for(int i =0;i<3;i++)
    {
    persfeld[i].getdata();
    file.write((char*) &persfeld[i],sizeof(person));
    if(!file.good())
    cout << "Fehler beim Schreiben!"<<endl;
    }

    file.close();
    // file.seekg(0,ios::beg);
    fstream file2;
    file2.open("G:\\people.dat",ios::in|ios::binary);
    if(!file2.good())
    cout<< "Fehler bei Dateihandling (open)" << endl;

    while(!file2.eof())
    {
    file2.read((char*)&pers,sizeof(pers));
    if(!file2.good())
    cout << "Fehler beim Lesen!" <<endl;
    else
    pers.showdata();

    }
    file2.clear();
    file2.close();

    return 0;
    }

    Das Programm tut auch was es soll, nur nach der Ausgabe der Daten (Lesen der Datei) schmiert danach das Programm ab und ich finde den Fehler einfach nicht. Googeln hat leider bisher auch nichts ergeben. Könnt ihr mir vielleicht helfen?
    Ich arbeite mit dem DevC++ und bekomme die Meldung: Programm funktioniert nicht mehr.
    Vielen Dank schon mal.



  • turing2 schrieb:

    ich beschäftige mich gerade mit dem Speichern von Objekten in Dateien und habe dazu folgendes kleines Prohgramm geschrieben:
    [...]

    Der Code hat sicherlich einige Unzulänglichkeiten, aber das größte Problem ist das data member name in class person .

    Es ist implementierungsabhängig aber schematisch sieht std::string wohl meist so aus:

    namespace std{
    template< blabla >
    class basic_string{
      CharT *data;
    public:
      /* usw. usf. */
    };
    }
    

    Der string hält die Daten über einen Zeiger. Und wenn Du so ein Objekt einfach in einen stream schreibst und wieder liest hast Du wahrscheinlich einen Fehler, weil Du nicht die Daten kopierst, sondern nur einen Zeiger (der dann auf meist weniger Sinnvolles zeigt).
    Stichworte: deep copy / shallow copy (tiefe Kopie / flache Kopie).



  • Hi turing2,

    Ausgabe auf die Konsole oder in einen Datei kann das selbe sein. Genauso ist in dem Fall Einlesen von Konsole und Einlesen von Datei das gleiche.

    #include <iostream>
    #include <fstream>
    #include <string>
    
    class person
    {
    private:
        std::string name;
        int alter;
    
    public:
        //  showdata bzw. Speichern
        friend std::ostream& operator<<( std::ostream& out, const person& p )
        {
            return out << p.name << "\n" << p.alter << std::endl;
        }
        // getdata (nur get-Teil)
        friend std::istream& operator>>( std::istream& in, person& p )
        {
            return getline( in >> std::ws, p.name ) >> p.alter;
        }
    };
    
    using namespace std;
    bool get_person_from_cin( person& p )
    {
        cout << "Name: <NewLine> Alter:\n";
        cin >> p;
        return cin.good();
    }
    
    int main() 
    {
        {
            person persfeld[3];
            ofstream file("G:\\people.dat"); // o -> output
            if(!file.good())
                cout<< "Fehler bei Dateihandling" << endl;
    
            for(int i =0;i<3;i++)
            {
                if( get_person_from_cin( persfeld[i] ) )
                {
                    file << persfeld[i];
                }
            }
            if( !cin.good() )
                cout << "Fehler beim Lesen von cin" << endl;
            if(!file.good())
                cout << "Fehler beim Schreiben!"<<endl;
        }   // ruft auch file.close()
    
        {
            ifstream file2("G:\\people.dat");   // i -> input
            if(!file2.good())
                cout<< "Fehler bei Dateihandling (open)" << endl;
    
            person pers;
            while( file2 >> pers )
            {
                cout << pers;
            }
            if( !file2.eof() )
                cout << "Fehler beim Lesen!" <<endl;
        }
        return 0;
    }
    

    Das Statement ' while(!file2.eof()) ' ist ein Virus, der sich aus den Köpfen vieler über das gesamte Internet verbreitet hat. Falsch ist es trotzdem.


Log in to reply