C++ In eine Txt schrieben und auslesen

AirForce

Lt. Junior Grade
Registriert
Okt. 2010
Beiträge
296
Brauche mal euer Hilfe. Schreibe mein ersten Programm das in eine txt Datei schreibt und dann aus dieser txt Datei lesen soll. Das Programm fragt nachzweimal sieben Nummer (x und y) und Speichert es im Vektor und auch in der Datei. Danach wird die Datei wieder geöffnet und es soll die Werte einlesen und in einem Vektor ablegen. Das einlesen habe ich gemacht doch ich will das der Vektor werte ausgegeben werden soll, und da komme ich nicht weiter.
Code:
using std::ofstream;
using std::endl; 

struct Point {
	int x, y;
	Point(int xx, int yy):x(xx),y(yy) {} 
};

int main()
{
	ofstream fout( "mydata.txt" ); 

	cout << "Geben Sie bitte den Namen der Ausgabedatei ein:";
	string name;
	cin>>name;
	ofstream ostr(name.c_str());
	if(!ostr) error("Fehler beim Oeffnen der Ausgabedatei",name); 

	vector <Point> original_points;
	for( int i = 0; i < 7; ++i )
	{
		cout << "Bitte geben sie einen x- und einen y-Wert ein: ";
		int x,y;
		cin>>x>>y;
		if (x  >= 10000 || x <= 0 || y <= 0 || y >= 10000) {cout << "ungueltiger wert" << endl; break;}
		original_points.push_back( Point(x,y) );
	}

	for (int i = 0; i < original_points.size(); ++i){
		fout << original_points[i].x << ',' << original_points[i].y << endl;
		cout << original_points[i].x << ',' << original_points[i].y << endl;}

	cout << "Geben Sie bitte den Namen der Eingabedatei ein:";
	cin>>name;
	ifstream istr(name.c_str());
	if(!istr) error("Fehler beim Oeffnen der Eingabedatei",name);
        vector <Point> processed_points; 
	int x,y;
        if(istr >> x >> y) 
        processed_points.push_back(Point(x,y));
	for (int i = 0; i < processed_point.size(); ++i){
	     cout << processed_point[i].x << ',' << processed_point[i].y << endl;}
     
    keep_window_open();
    return 0;
}
Ergänzung ()

Habe den Code korrigiert. Doch jetzt werden statt der zweimal sieben werte mehr werte ausgegeben und das ist das Problem. Aber wieso?
Code:
cout << "Geben Sie bitte den Namen der Eingabedatei ein:";
	cin>>name;
	ifstream istr(name.c_str());
	if(!istr) error("Fehler beim Oeffnen der Eingabedatei",name);
        vector <Point> processed_points; 
	int x,y;
	char c;
        while (!istr.eof()){ 	
        if(istr >> x >> c >> y) 
        processed_points.push_back(Point(x,y));
        for(vector<Point>::iterator i = processed_points.begin(); i != processed_points.end(); ++i) 
	    cout << i->x << "," << i->y << endl;}
Ergänzung ()

Wieder Code überarbeitet jetzt werden auch so viele werte ausgeben wie es sein sollte, so weit so gut aber jetzt Stürzt das Programm ab
Code:
int main()
{
	ofstream fout( "mydata.txt" ); 

	cout << "Geben Sie bitte den Namen der Ausgabedatei ein:";
	string name;
	cin>>name;
	ofstream ostr(name.c_str());
	if(!ostr) cerr << "Fehler beim Oeffnen der Ausgabedatei" << name << endl; 

	vector <Point> original_points;
	for( int i = 0; i < 7; ++i )
	{
		cout << "Bitte geben sie einen x- und einen y-Wert ein: ";
		int x,y;
		cin>>x>>y;
		if (x  >= 10000 || x <= 0 || y <= 0 || y >= 10000) {cout << "ungueltiger wert" << endl; break;}
		original_points.push_back( Point(x,y) );
	}

	for (int i = 0; i < original_points.size(); ++i){
		fout << original_points[i].x << ',' << original_points[i].y << endl;
		cout << original_points[i].x << ',' << original_points[i].y << endl;}

	cout << "Geben Sie bitte den Namen der Eingabedatei ein:";
	cin>>name;
	ifstream istr(name.c_str());
	if(!istr) cerr << "Fehler beim Oeffnen der Eingabedatei" << name << endl;
        vector <Point> processed_points; 
	int x,y;
	char c;

	while (!istr.eof()){ 	
        if(istr >> x >> c >> y) 
        processed_points.push_back(Point(x,y));
        for (int i = 0; 7 > processed_points.size(); ++i){
	     cout << original_points[i].x << ',' << original_points[i].y << endl;}
	}
 
Wirf doch mal den Debugger an und schau, wann er genau ein Problem hat und welches.

Was mir auffällt: Du solltest die Ausgabedatei schließen, bevor du sie einliest.


Gruß,

badday
 
Es sagt Debug Error! R6010 -abort has been called
Habe es mit ostr.close() geschlossen.
 
Zuletzt bearbeitet:
Ja, ich meinte std::ofstream::close()

Welche Entwicklungsumgebung benutzt du?
Lasse den Debugger mal Schritt für Schritt durchlaufen und setze Breakpoints. Dann schau dir mal den Callstack und die genau Fehlermeldung an.
 
Die IDE ist Visual Studio 2010. Der Fehler kommt immer nachdem ich die Werte ausgegeben habe. Ich denke hier ist der Fehler, weil alles lief ohne Fehler bis ich diese Zeile eingegeben habe:
Code:
for (int i = 0; 7 > processed_points.size(); ++i){
		 cout << original_points[i].x << c << original_points[i].y << endl;}
Als ich das geschrieben habe waren keine abstürze:
Code:
for (int i = 0; i < processed_points.size(); ++i){
		 cout << original_points[i].x << c << original_points[i].y << endl;}
Nur des gab den Fehler das die Werte mehr mal ausgegeben wurden.
 
Zuletzt bearbeitet:
Ich kann nicht ganz nachvollziehen, was du da treibst (?). processed_points.size() wird sich mit keiner Iteration der for-Schleife ändern. Folglich hast du, wenn 7 > processed_points.size() gilt, eine Endlosschleife, die dadurch beendet wird, dass du irgendwann original_points mit einem i aufrufst, das größer als original_points.size() sein wird.

Soweit ich das sehe, willst du sowas wie

Code:
while (!istr.eof()) 	
        if(istr >> x >> c >> y) 
              processed_points.push_back(Point(x,y));

for (int i = 0; i < processed_points.size(); ++i)
     cout << processed_points[i].x << ',' << processed_points[i].y << endl;
Ergänzung ()

Noch ein kleiner Tipp: Es ist sehr komfortabel, die STL zu nutzen:

Code:
for(std::vector<Point>::iterator iter = processed_points.begin(); iter != processed_points.end(); ++iter)
              std::cout << iter->x << ',' << iter->y << std::endl;
 
Zuletzt bearbeitet:
Das ist ein dummer Typ Fehler. Habe eine Korrektur gemacht, aber es ist eine endlos schleife
Code:
while (!istr.eof()){ 	
     if(istr >> x >> c >> y) 
		 processed_points.push_back(Point(x,y));
	 

	 for (int i = 0; i < processed_points.size(); ++i){
		 cout << x << ',' << y << endl;} 
     }
Also noch mal es soll die Werte in einem vector einlesen was auch gemacht wurde:
Code:
while (!istr.eof()){ 	
     if(istr >> x >> c >> y) 
		 processed_points.push_back(Point(x,y));
Jetzt will ich nur die Werte von vector (processe_points) ausgeben, nur das will ich.
 
Zuletzt bearbeitet:
Du willst doch erstmal die Datei einlesen? Dann ist doch die while-Schleife darauf begrenzt (?)

Die for-Schleife dient der Ausgabe. Hier solltest du dann den oben von mir geschrieben Code benutzen. Falls processed_points valide Werte enthält, sollte das funktionieren.

Ansonsten poste bitte mal deinen kompletten Code.
 
Der ganze Code:
Code:
struct Point {
	int x, y;
	Point(int xx, int yy):x(xx),y(yy) {} 
};

int main()
{
	ofstream fout( "mydata.txt" ); 

	cout << "Geben Sie bitte den Namen der Ausgabedatei ein:";
	string name;
	cin>>name;
	ofstream ostr(name.c_str());
	if(!ostr) cerr << "Fehler beim Oeffnen der Ausgabedatei" << name << endl; 

	vector <Point> original_points;
	for( int i = 0; i < 7; ++i )
	{
		cout << "Bitte geben sie einen x- und einen y- Wert ein: ";
		int x,y;
		cin>>x>>y;
		if (x  >= 10000 || x <= 0 || y <= 0 || y >= 10000) {cout << "ungueltiger wert" << endl; break;}
		original_points.push_back( Point(x,y) );
	}

	for (int i = 0; i < original_points.size(); ++i){
		fout << original_points[i].x << ',' << original_points[i].y << endl;
		cout << original_points[i].x << ',' << original_points[i].y << endl;}

	ostr.close();

	cout << "Geben Sie bitte den Namen der Eingabedatei ein:";
	cin>>name;
	ifstream istr(name.c_str());
	if(!istr) cerr << "Fehler beim Oeffnen der Eingabedatei" << name << endl;
        vector <Point> processed_points; 
	int x,y;
	char c;

	while (!istr.eof()){ 	
        if(istr >> x >> c >> y) 
		 processed_points.push_back(Point(x,y));
	 

	 for (int i = 0; i < processed_points.size(); ++i){
		 cout << processed_points[i].x << ',' << processed_points[i].y << endl;}
	
    }
	
    keep_window_open();
    return 0;
}
Es soll aus der Txt Datei in dem Vektor processed_points einlesen, und danach sollen die Werte ausgegeben werde.
 
Zuletzt bearbeitet:
Das funktioniert doch eigentlich ;)

Allerdings: Du speicherst die Werte grundsätzlich in mydata.txt, nicht aber in der Ausgabedatei, deren Namen du abfrägst.


Code:
while (!istr.eof())	
{
        if(istr >> x >> c >> y) 
		 processed_points.push_back(Point(x,y));
}
	 

for (int i = 0; i < processed_points.size(); ++i)
		 cout << processed_points[i].x << ',' << processed_points[i].y << endl;

verrichtet das, was du willst, erst das Einlesen, dann das Ausgeben.


Gruß,

badday
 
Danke für deine Hilfe, wie es aussah hatte ich Typ Fehler, es wurden leide zu viele klammern geschrieben.
Muss noch eine Sache machen dann ist das Programm fertig.
Ergänzung ()

Jetzt eine Frage wie könnte man das machen wenn das Programm die Werte in die Txt Datei schreibt dann wird ja Ausgabe Stream ostr mit close() geschlossen. Aber wieso gibt das Programm die Datei nicht frei? Ich wil nach dem reinschreiben die Txt öffnen und einen Wert verändern (das mache ich mit dem Editor) und dann einlesen, es gibt eine Prüfung die die Werte der zwei Vektor vergleicht. Wenn alles gleich ist ist es OK aber wenn die Werte nicht stimmen wird eine Meldung ausgegeben.
 
Zuletzt bearbeitet:
badday schrieb:
Code:
while (!istr.eof())	
{
        if(istr >> x >> c >> y) 
		 processed_points.push_back(Point(x,y));
}
	 

for (int i = 0; i < processed_points.size(); ++i)
		 cout << processed_points[i].x << ',' << processed_points[i].y << endl;
Zwei fiese Fehler.

Das while ist potenziell eine Endlosschleife. Schlägt das Parsen mit istr >> ... fehl, so ist das failbit gesetzt, eof aber nicht. Die extractors agieren bei gesetztem failbit aber als No-Ops. Den eof()-Test einfach durch ein while (istr) ersetzen, dann klappt's auch mit dem Abbruch im Fehlerfall. :)

Eine Trennung der Zahlen einfach nur mit Komma und ohne Leerzeichen ist locale-abhängig. 1,500 wäre in einem amerikanischen Locale z.B. die Zahl 1500 (, ist das Tausender-Trennzeichen). Am besten bei beiden filestreams ein stream.imbue(std::locale("C")); machen.
 
Beides berechtigte Anmerkungen, allerdings wohl irrelevant für das was er vorhat ;)
 
Das mag sein, aber früh lernt sich... :) Lieber direkt von Anfang an richtig machen und wissen, dass dort Fehlerpotenzial lauert, sonst wiederholt man das "falsch" gelernte und stolpert irgendwann drüber. Mein's ja nur gut. ;)
 

Ähnliche Themen

Zurück
Oben