Wo ist mein Fehler?



  • Hallo, ich habe gerade ein Programm in c++ geschrieben, die ausgabe ist aber nicht wirklich so, wie ich mir das vorgestellt habe...
    könnt ihr mir sagen wo ich einen Fehler gemacht habe?

    #include <iostream>
    #include <string>
    #include <fstream>
    #include <sstream>
    using namespace std;
    struct Demo
    {
    	int wert;
    	string text;
    };
    
    Demo strukturen[10];
    
    int main()
    {
    	ifstream dat_ein;
    	ofstream dat_aus;
    
    	// Array mit Strukturen initialisieren
    
    	stringstream sstream;
    	for (int n = 0;n < 10; n++)
    	{strukturen[n].text;
    	sstream << n;
    	sstream >> strukturen[n].text;
    	sstream.clear();
    	strukturen[n].text += ". Strukturvariable";
    	}
    
    	// Ausgabedatei oeffnen
    
    	dat_aus.open("Ausgabe.dat", ios_base::out);
    	if (!dat_aus)
    	{
    		cerr << "datei konnte nicht geoeffnet werden!\n";
    			return 1;
    	}
    	// Array mit Strukturen in Datei schreiben
    
    	dat_aus.write((char *) strukturen, sizeof(struct Demo)*10);
    
    	dat_aus.close();
    
    	// Eingabedatei oeffnen
    	dat_ein.open("Ausgabe.dat", ios_base::in);
    	if (!dat_ein)
    	{
    		cerr << "Datei konnte nicht geoeffnet werden!\n";
    		return 1;
    	}
    
    	// strukturen einlesen
    	int n = 0;
    	while(!dat_ein.eof())
    	{
    		dat_ein.read((char *) &strukturen[n],sizeof(struct Demo));
    		n++;
    	}
    
    	// eingelesene Strukturen auf dem Bildschirm ausgeben
    	for (int n = 0; n < 10; n++)
    	{
    		cout << strukturen[n].text << endl;
    		cout <<"\t" << strukturen[n].wert << endl;
    	}
    	dat_ein.close();
    	return 0;
    }
    


  • Wie soll die Ausgabe denn lauten?
    stringstream.clear löscht nicht dessen Inhalt. Binäres Schreiben und Lesen von nicht-POD Daten wie deine Strukturen geht meist schief.



  • In der datei soll die im speicher angetroffene Bitfolge geschrieben werden.



  • Techel schrieb:

    Binäres Schreiben und Lesen von nicht-POD Daten wie deine Strukturen geht meist schief.

    Ich schreibe das von einem Buch das mir beim programmieren lernen hilft 😃



  • der fehler liegt daran, dass du einen std::string ziemlich brutal in char* konvertierst. oder anders gesagt, du verwendest die iostream-api nicht richtig.

    #include <iostream>
    #include <iomanip>
    //...
    
    std::ofstream fout{"Ausgabe.dat"}; //warum extra ios::out angeben?
    
    for (auto const& demo: strukturen) {
      fout << demo.wert << std::quoted(demo.text) << '\n';
    }
    
    //...
    std::ifstream fin("Ausgabe.dat"};
    
    while (fin) {
       Demo tmp;
       fin >> tmp.wert >> std::quoted(tmp.text);
       //do something with tmp ...
    }
    


  • und die anmerkungen zum ursprungscode

    #include <iostream>
    #include <string>
    #include <fstream>
    #include <sstream>
    using namespace std;
    struct Demo
    {
    	int wert;
    	string text;
    };
    
    Demo strukturen[10];
    
    int main()
    {
    	ifstream dat_ein; //wozu bereits hier anführen? du verwendest dat_ein und dat_aus erst viel weiter unten.
    	ofstream dat_aus; //also runter damit!
    
    	// Array mit Strukturen initialisieren
    	stringstream sstream; //ab in die schleife damit, dann ersparst du dir dort das stream.clear();
    	for (int n = 0;n < 10; n++) //die einrückungen hier sind unüblich, was sie schwer lesbar macht.
    	{strukturen[n].text; //wozu diese zeile? 
    	sstream << n;
    	sstream >> strukturen[n].text;
    	sstream.clear(); //das 
    	strukturen[n].text += ". Strukturvariable";
    	}
    
    	// Ausgabedatei oeffnen
    
    	dat_aus.open("Ausgabe.dat", ios_base::out); //wozu ios::out?
    	if (!dat_aus)
    	{
    		cerr << "datei konnte nicht geoeffnet werden!\n";
    			return 1;
    	}
    	// Array mit Strukturen in Datei schreiben
    	//HIER crasht alles *GANZ* böse. 
            //ein hinweis darauf ist der C-style cast (char*) - sobald du soetwas verwenden willst, hau dir auf die finger. 
    	dat_aus.write((char *) strukturen, sizeof(struct Demo)*10);
            //wie kommst du außerdem auf sizeof(struct Demo)? da hast du wohl ein wirklich seltsames buch...
    
    	dat_aus.close(); //wäre unnötig, wenn du den code für die ausgabe und den code für die eingabe jeweils in eine eigene funktion packen würdest. 
            //wäre üblich und damit wieder: lesbarer.
    
    	// Eingabedatei oeffnen
    	dat_ein.open("Ausgabe.dat", ios_base::in);
    	if (!dat_ein)
    	{
    		cerr << "Datei konnte nicht geoeffnet werden!\n";
    		return 1;
    	}
    
    	// strukturen einlesen
    	int n = 0;
    	while(!dat_ein.eof())
    	{
                    //hier das zweite mal ein großes *CRASH*
    		dat_ein.read((char *) &strukturen[n],sizeof(struct Demo));
                    //überleg dir mal: was wäre denn eigentlich sizeof(struct Demo)?
                    //sizeof(struct Demo) liefert dir *immer* denselben wert. unabhängig davon, ob in dem string zwei, vier oder eine milliarde zeichen stehen.
    		n++;
    	}
    
    	// eingelesene Strukturen auf dem Bildschirm ausgeben
    	for (int n = 0; n < 10; n++)
    	{
    		cout << strukturen[n].text << endl;
    		cout <<"\t" << strukturen[n].wert << endl;
    	}
    	dat_ein.close();
    	return 0;
    }
    

    teile den code auf verschiedene funktionen auf. deklariere deine variablen so spät wie möglich. vermeide casts - und wenn du denkst, du musst, dann denk dir zuallererst: da mach ich sicher etwas falsch damit.

    welches buch verwendest du? und was steht da wirklich drin?



  • das ist mir noch etwas zu viel, ich mach mal weiter mit dem nächsten kapitel und komm dann später darauf zurück 😃 ich hab bis jetzt noch nicht mit iomanip gearbeitet..



  • dove schrieb:

    und die anmerkungen zum ursprungscode

    welches buch verwendest du? und was steht da wirklich drin?

    Ich verwende das Buch "Jetzt lerne ich c++" und wenn ich jetzt keine fehler gemacht habe steht das da so drin wie ich es geschrieben hab



  • das steht halt immer so drin wieweit man schon gelernt hat und aus dem buch hab ich eigentlich alles was ich bisher mit c++ gemacht habe



  • nicopro98 schrieb:

    das ist mir noch etwas zu viel, ich mach mal weiter mit dem nächsten kapitel und komm dann später darauf zurück 😃 ich hab bis jetzt noch nicht mit iomanip gearbeitet..

    OK, tut mir leid. iomanip ist für std::quoted, eine hilfsfunktion ab C++14 um strings mit leerzeichen einfach auszugeben und einzulesen.

    ich kenne das buch nur über die leseprobe von amazon und kann daher nicht beurteilen, wie gut es ist, aber schaumal auf seite 77 (kapitel 3.5.3) - da geht es um "explizite typumwandlungen" (casts).

    der fehler, den du gemacht hast, ist, dass du dein "struct Demo" zu einem zeiger auf char (char*) konvertierst, um es via "write" in den ausgabestream zu schreiben. dir muss im wesentlichen nur klar sein, dass struct Demo nicht dasselbe ist, wie eine zeichenketter (zeiger auf char). ich denke, das ist nicht so schwer verständlich, oder?

    im prinzip musst du, wenn du dein struct Demo ausgeben willst, dem compiler sagen, "wie" es ausgegeben werden soll. die übliche C++ variante dafür ist, operator<< und operator>> zum ein- und auslesen für streams zu überladen. das ist in deinem buch zwar erst auf seite 397 (kapitel 22.3.4) im "profikurs" angesprochen, hat aber im wesentlichen nichts mit "profi" zu tun, sondern ist eine sehr, sehr einsteigerfreundliche methode, selbstdefinierte klassenobjekte in streams zu schreiben und wieder einzulesen. im prinzip kannst du dir das kapitel über streams sparen, wenn du nicht zuerst das kapitel 22.3.4 gelesen hast.



  • ok danke fur die hilfe ich bin jetzt eh schon beim nächsten kapitel wenn ich noch fragen hab komm ich nochmal hierher das heist ihr werdet mich hier auf jeden fall nicht nur ein mal wieder sehen XD



  • das wichtigste ist, fragen zu stellen. vor allem hier im forum wird dir sicherlich gerne geholfen. ich hab so auch angefangen mit C++ (und was für einen stuss ich produziert habe... anno oh mein gott bin ich alt)



  • haha naja zumindest meinen Taschenrechner hab ich zum laufen gebracht 😃


Anmelden zum Antworten