Problem mit if-Anweisung beim Datei einlesen

LadyMarion

Mitglied
Hallo,

ich habe eine Funktion, mit der ich Werte aus einer Datei einlesen möchte.
Die Funktion an sich funktioniert, jedoch hab ich noch ein kleines Problem:

Die Datei sieht folgendermaßen aus:
#Version2

WertA WertB WertC
1.23 4.56 7.89

Die Datei sieht immer gleich aus, es kann lediglich sein, dass der WertB und somit die ganze Spalte fehlt.

Meine Funktion sieht so aus:
Code:
void read()
{
	ifstream IN ("test.txt");
	if (IN.is_open()) {
		bool WertB_ = false;
		string line;

		while (!IN.eof())
		{
			getline(IN, line);
			if (line.find("VERSION>2<") != string::npos)
				typ = "2";
			else if (line.find("VERSION>3<") != string::npos)
				typ = "3";
			else
			{
				cerr<<"# Invalid file!"<<endl;
				exit(-1);
			}

			if((line.find("WertB") != string::npos))
				WertB_ = true;

			if (!line.empty() && line[0] != '#')
			{
				for (unsigned int i = 0; i < lines.size(); ++i)
				{
					stringstream sstr;
					sstr << line;
					// hier werden die Werte dann gelesen, usw...
				}
			}
			if (!WertB_)
				cout<<"Old version!"<<endl;
		}
	}
	else
	{
		cerr<<"# Error opening file!"<<endl;
		exit(-1);
	}
}

Wie gesagt, im Prinzip funktioniert die Funktion. Die Funktion ist noch etwas umfangreicher, aber ich habe jetzt nur die relevanten Sachen geschrieben.

Die Fehler bzw. Probleme sind folgende:
Am Anfang soll die Version der Datei abgefragt werden, dementsprechend werden die Werte dann unterschiedlich rausgelesen. Sobald z.B. die Version2 gefunden ist, soll die if-Anweisung verlassen werden. Denn wenn die anderen Zeilen eingelesen werden, wird natürlich immer der else-Teil aufgerufen und das Programm beendet.
Dasselbe gilt für die Abfrage, ob WertB vorhanden ist. Auch hier kommt ständig die Fehlermeldung für alle Zeilen, die kein "WertB" enthalten.
Weil es in dieser while-Schleife mit diesem getline drin ist, werden diese if-Anweisungen halt immer wieder aufgerufen. Aber außerhalb dieser while-Schleife funktioniert es halt auch nicht.

Kann mir da jemand einen Tipp geben, wie diese if-Anweisungen nicht ständig durchlaufen werden?

Vielen Dank!
 
Hallo random-access,

vielen Dank für Deine Antwort.

Das "break" hab ich schon probiert, das funktioniert aber nicht. Da bricht das Programm dann nämlich zu früh ab.
Die vielen Fehlermeldungen werden dann zwar nicht mehr ausgegeben, aber die Werte werden auch nicht eingelesen...
 
Hi.
Code:
void read()
{
	ifstream IN ("test.txt");
	if (IN.is_open()) {
		bool WertB_ = false;
		string line;

		while (!IN.eof())
		{
			getline(IN, line);
			if (line.find("VERSION>2<") != string::npos)
...
So geht das schonmal gar nicht. Die eof() Methode solltest du nicht auf diese Weise verwenden. Das funktioniert so nicht. Siehe z.B. http://www.tutorials.de/forum/c-c/243283-ifstream-ofstream.html#post1266796 oder such im Forum nach getline und eof.

Dann liest du mit getline eine Zeile. Aber woher willst du wissen, ob überhaupt eine Zeile eingelesen wurde?! Das prüfst du gar nicht ab.

Falls der Stream in einen anderen Fehlerzustand als EOF geht, hast du eine schöne Endlosschleife...

Dann steht ja die Version immer in der ersten Zeile, oder?! Da würde ich auch erstmal nur die erste Zeile einlesen und die Version prüfen. Danach in einer Schleife alle weiteren Daten verarbeiten:
C++:
if (getline(IN, line)) {
  // prüfe Version...
  if (Version != OK) {
    // Fehler
  } else {
    while (getline(IN, line)) {
      // Zeile verarbeiten
    }
  }
}
Gruß

PS: Üblicherweise bezeichnet man nur Präprozessormakros und -Variablen mit Großbuchstaben.
 
Hallo deepthroat,

vielen Dank für Deine Antwort!

Ich hab das jetzt geändert und soweit funktioniert es jetzt auch.

Jetzt habe ich allerdings noch ein anderes Problem:

Meine Datei sieht folgendermaßen aus:

# VERSION>2<
# Kommentar
#
# WertA WertB WertC WertD
1.23 4.56 7.89 on
1.32 4.65 7.98 off
3.21 6.54 9.87 on

Meine Funktion sieht jetzt so aus (habe alles nicht relevante weggelassen):
Code:
void read()
{
    ifstream IN ("test.txt");
    if (IN.is_open())
    {
	vector<string> lines;
	string line;
	bool wertB_ = false;

	if (getline(IN,line))
	{
	    if (line.find("VERSION>2<") != string::npos)
		typ = "2";
	    else
	    {
		cerr <<"# Invalid file!"<<endl;
		exit(-1);
	    }

	    while (getline(IN,line))
	    {
		if((line.find("WertB") != string::npos))
		    wertB_ = true;

		if (!line.empty() && line[0] != '#')
		{
		    lines.push_back(line);
		    stringstream sstr;
		    string onoff;
		    double a, b, c;
		    for (unsigned int i = 0; i < lines.size(); ++i)
		    {
			sstr << line;
			if (line == lines[i])
			{
			    if (line.find("on") != string::npos)
			    {
				if (typ == "2")
				{
				    if (wertB)
					sstr >> a >> b >> c >> onoff;
				    else
					sstr >> a >> c >> onoff;
				}
				data[i+1]["a"] = a; // ist in der Klasse als "map<int, map<string,double> > data;" festgelegt
				data[i+1]["b"] = b;
				data[i+1]["c"] = c;
			    }
			}
		    }
		}
	    }
	    if (!wertB_)
		cout<<"Old version!"<<endl;
	}
    }
    else
    {
	cout<<"ERROR opening file"<<endl;
	exit(-1);
    }
}

Wenn ich die Funktion nun irgendwo aufrufe und die Werte z.B. so auslesen will:
data[1]["a"] = 1.23
data[2]["a"] = 0 // wobei hier nicht 0, sondern die Meldung "Fall ist off!" erscheinen soll
data[4]["a"] = 0 // hier das gleiche: nicht 0, sondern "Fall gibt es nicht!"

Irgendwie bekomm ich das nicht hin... :confused:
 
Hi.
Wenn ich die Funktion nun irgendwo aufrufe und die Werte z.B. so auslesen will:
data[1]["a"] = 1.23
data[2]["a"] = 0 // wobei hier nicht 0, sondern die Meldung "Fall ist off!" erscheinen soll
data[4]["a"] = 0 // hier das gleiche: nicht 0, sondern "Fall gibt es nicht!"

Irgendwie bekomm ich das nicht hin... :confused:
Du solltest dir mal die Referenz der std::map etwas genauer ansehen.

Wenn du auf ein Element mit dem operator[] zugreifst wird das Element angelegt, falls es noch nicht in der Map existiert. Wenn du prüfen willst, ob ein Element schon enthalten ist, kannst du die count() Methode verwenden:
C++:
if (data.count(4) == 0 || data[4].count("a") == 0) {
  cerr << "Fehler: Fall gibt es nicht.\n";
}
Gruß
 
Zurück