C++ Problem beim Einlesen einer Textdatei

darton

Lt. Junior Grade
Registriert
Okt. 2004
Beiträge
282
Hallo!
Ich habe eine Textdatei, die ungefähr so aussieht:
Code:
# some comment

1 1 1 1
6 5 2 1
12 0 3 1
2.5 5 3 1
5 3 4 3

4 3 3
7 5 3
10 4 1
Diese möchte ich nun mit C++ einlesen. Mein Code sieht bisher wie folgt aus:
Code:
ifstream file("datei.txt");
    if (file) {
        string line;
        double x, y, z;   
        int p_class;
        while (getline(file, line)) {            
            if (line.empty() || line[0] == '#') //Kommentare und Leerzeilen ignorieren
                continue;            
            istringstream ss(line);
            ss >> x;
            ss >> y;
            ss >> z;            
            if (!ss.eof()) {         //wenn 4 Zahlen in einer Zeile       
                ss >> p_class;                
                Point p(x, y, z, p_class);
                training.push_back(p);                
            } else {                 //wenn 3 Zahlen in einer Zeile
                Point p(x, y, z);                
                test.push_back(p);
            }
        }        
    }
Kompilierfehler gibts keine. Wenn ich das Programm aber ausführe, bleibt der irgendwo hängen. Ich hab mir mal was auf die Konsole ausgeben lassen und dann festgestellt, dass nur der erste Block ausgegeben wird, also bis zu der Zeile, die mit einer 5 beginnt. Danach passiert einfach nichts mehr, das Programm bricht aber auch nicht ab. Ich dachte erst Endlosschleife, aber dann müsste ja eigentlich weiterhin was ausgegeben werden. Kann jemand den Fehler finden?
 
Hab mich oben vertan, bis zur Zeile "10 4 1" läuft der problemlos durch. Sogar, wenn ich außerhalb der while-Schleife etwas schreibe, wird das noch ausgegeben :S. Allerdings terminiert der einfach nicht, also ich muss Strg-C drücken, damit ich aus dem Programm rauskomme.

Übrigens, wenn ich in der letzten Zeile, also in "10 4 1", hinter der 1 ein Leerzeichen (also Whitespace) einfüge, dann terminiert das Programm. Allerdings wird dann etwas falsch eingelesen, sodass dies keine Lösung für das Problem wäre.
Ergänzung ()

OK, ich hab ein weiteres Mysterium rausgefunden. Wenn ich die Zeilen
Code:
training.push_back(p);
und
Code:
test.push_back(p);
auskommentiere läuft das Programm durch. training und test werden im Header als Objektvariablen wie folgt definiert:
Code:
vector<Point> training;
vector<Point> test;
Wie kann das sein?
 
Zuletzt bearbeitet:
also mit g++ 4.5.2 und MSVC 2010 gibt es keine Probleme. Ich habe folgenden Source probiert:

Code:
#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>

using namespace std;

struct Point {
	double x_, y_, z_;
	int p_;

	Point(double x, double y, double z)
		: x_(x)
		, y_(y)
		, z_(z)
		, p_(-1)
		{}
		
	Point(double x, double y, double z, int p)
		: x_(x)
		, y_(y)
		, z_(z)
		, p_(p)
		{}
	
};

int main () {
	vector<Point> test, training;
	
	ifstream file("datei.txt");
    if (file) {
        string line;
        while (getline(file, line)) {            
            if(!line.empty() && line[0] != '#') {
				istringstream ss(line);
				double x, y, z;   
				if(ss >> x >> y >> z) {            
					int p_class;
					if(ss >> p_class) {
						cout << "P4:" << x << y << z << p_class << endl;
						Point p(x, y, z, p_class);
						training.push_back(p);
					}
					else {
						cout << "P3:" << x << y << z << endl;
						Point p(x, y, z);                
						test.push_back(p);
					}
				}
				else 
					cerr << "Ups, unerwartete Zeile '" << line << "'\n";
			}
        }        
    }
}

Wahrscheinlich liegt das Problem außerhalb des geposteten Codes.
 
OK, jetzt funktioniert alles. Aber fragt nicht warum. Eventuell hat einfach das Löschen aller o-Dateien geholfen.
 
Als Hinweis, da in der Datei "2.5" steht - das ist vom eingestellten Locale abhängig. Mit deutschem Locale würde das nicht verstanden und stattdessen "2,5" erwartet.
Also beim Schreiben und Lesen jeweils ein stream.imbue(locale()) machen - das stellt das Standard-C-Locale ein und dann funktioniert das Schreiben und Einlesen auch unabhängig von der Spracheinstellung.

Und, alle Objects löschen kann Wunder bewirken. ;-) Wenn da etwas veraltet ist, scheint dein Make-Support aber nicht ganz sauber zu sein. Mit was arbeitest du denn? (Plattform, Compiler, etc)
 
Ah okay - dann solltest du dir ggf. mal anschauen, wie man ein einfaches Makefile schreibt, so schwer ist das garnicht. :) Damit lassen sich solche Unannehmlichkeiten ganz gut vermeiden.
 
Zurück
Oben