txt-Datei öffnen und immer bis Zeilenende einlesen
-
Hy!
Also Ich bin noch recht am Anfang von C++ und hab mir auch schon die FAQ-Einträge zu Dateien in C++ durchgelesen. Es hat mir einiges veranschaulicht, aber zur Problemlösung hat es mir nicht viel gebracht, da so gut wie alle Beispiele mit Befehlen und Methoden funktionierten, die ich noch nicht gelernt habe.
Ich habe folgendes Problem:
Ich soll aus einer Datei (ini.txt) 5 FLOAT und einen String, der entweder "auf" oder "zu " lautet. Die Datei ini.txt ist so aufgebaut, dass , erst die 5 FLOAT kommen, und nach jeder Zahl ein Zeilenumbruch. Als letztes dann die Zeichenfolge und das wars.Ich habe es bisher nur geschafft in die ini.txt nur den String reinzuschreiben und versuche ihn auszulesen. Ich weiß nicht, wie ich es ausdrücken kann, dass immer nur bis zum Zeilenende gelesen werden soll. Ich finde nur den Ausdruck quelle.eof in dem *** Skript von meinem Prof. Aber nicht mal das funktioniert.
Hier mein bisheriger Versuch:
(pDatei = ini.txt,
pAusgabe ist eine Klasse, die eine Ausgabe gestaltet)char deckel_f[4]; ifstream quelle(pDatei, ios::in); // oeffnet Datei if(!quelle) cerr << "Fehler! " << pDatei << " kann nicht geoeffnet werden" << endl; else { char cpy; int i = 0; while(!quelle.eof()) { quelle >> cpy; deckel_f[i] = cpy; i++; } quelle.close(); } cout << deckel_f << endl; if(!(strcmp(deckel_f, "zu"))) { deckel = 'z'; pAusgabe->zeige("zu "); } else if(!(strcmp(deckel_f, "auf"))) { deckel = 'a'; pAusgabe->zeige("auf"); } else { cerr << "Fehler! " << pDatei << " konnte nicht gelesen werden" << endl; deckel = 'a'; pAusgabe->zeige("auf"); }DAnke schonmal

-
Verwende doch getline um immer die ganzen zeilen einzulesen. Außerdem wäre es eine gute Idee statt der char-Arrays std::string zu nehmen.
-
Braunstein schrieb:
Verwende doch getline um immer die ganzen zeilen einzulesen. Außerdem wäre es eine gute Idee statt der char-Arrays std::string zu nehmen.
getline geht leider nur mit string, und "string" hatte ich noch nicht. d.h. ich kanns auch leider nicht benutzen. (zudem funktionieren anscheinend die funktionen wie strcpy etc nicht mit "string").
werde es wohl anders machen müssen: erst die komplette datei einlesen in einen char-array und dann bei '\n' immer abtrennen.
und dann noch in floats konvertieren. oh man, mal schaun ob ich das hinbekomm...hab nur ein problem:
irgendwie macht das eof nicht richtig. wenn ich alles einlese bis (!quelle.eof) steht in dem array danach immernoch voll der mist. macht der da kein \0 am ende hin?
-
ODER:
gibt es eine möglichkeit die getline-funktion zu benutzen mit char-arrys? nicht oder? also mein compilter mozt rum wied sau

oder kann man dieses "string" einfach in nen char array umwandeln? ich hab ehrlich gesagt keinen plan was "string" ist, und in den faqs steht immer dauernd was von vector und container etc. auch noch keinen schimmer.
für nen anfänger bring die faq nicht viel
-
Es gibt zwei getline-Funktionen. Eine ist arbeitet in der tat nur mit std:.string zusammen und ist auch im selben Header mit deklariert. Die andere Variante ist eine Memberfunktion von istream und arbeitet mit char-Arrays zusammen. Die könntest du ja nehmen.
http://www.dinkumware.com/manuals/?manual=compleat&Search=getline&page=istream.html#basic_istream::getline
std::string ist eine Klasse für Strings welche das Handling gegenüber char-Arrays deutlich vereinfacht. Z.Bsp. hat sie eine eigene Speicherverwaltung, so dass du dich darum nicht selber kümmern mußt.
Eine Referenz findest du z.Bsp. hier
http://www.dinkumware.com/manuals/?manual=compleat&page=string2.html#basic_string::basic_string
hier noch weiter Seiten
http://www.hlrs.de/people/mueller/tutorials/script/scriptse30.html
-
ex.aveal schrieb:
Ich soll aus einer Datei (ini.txt) 5 FLOAT und einen String, der entweder "auf" oder "zu " lautet. Die Datei ini.txt ist so aufgebaut, dass , erst die 5 FLOAT kommen, und nach jeder Zahl ein Zeilenumbruch. Als letztes dann die Zeichenfolge und das wars.
das geht einfach mit:
#include <string> #include <fstream> #include <iostream> using namespace std; int main() { const char* pDatei = "ini.txt"; float f1, f2, f3, f4, f5; string aufZu; ifstream datei( pDatei ); if( !datei.is_open() ) cerr << "Fehler beim Oeffnen der Datei " << pDatei << endl; if( datei >> f1 >> f2 >> f3 >> f4 >> f5 >> aufZu ) { cout << "Lesen ok" << endl; if( aufZu == "auf" ) { cout << "Text war 'auf'" << endl; } else if( aufZu == "zu" ) { cout << "Text war 'zu'" << endl; } // .. usw. } else cerr << "Fehler beim Lesen" << endl; return 0; }ex.aveal schrieb:
oder kann man dieses "string" einfach in nen char array umwandeln?
kann man mit der Methode c_str(); muss man aber nicht. Wenn Du nur wissen willst, ob es "auf" oder "zu" war, so kannst Du es einfach so machen wie in meinem Vorschlag oben.
Gruß
Werner
-
Werner Salomon schrieb:
ex.aveal schrieb:
Ich soll aus einer Datei (ini.txt) 5 FLOAT und einen String, der entweder "auf" oder "zu " lautet. Die Datei ini.txt ist so aufgebaut, dass , erst die 5 FLOAT kommen, und nach jeder Zahl ein Zeilenumbruch. Als letztes dann die Zeichenfolge und das wars.
das geht einfach mit:
#include <string> #include <fstream> #include <iostream> using namespace std; int main() { const char* pDatei = "ini.txt"; float f1, f2, f3, f4, f5; string aufZu; ifstream datei( pDatei ); if( !datei.is_open() ) cerr << "Fehler beim Oeffnen der Datei " << pDatei << endl; if( datei >> f1 >> f2 >> f3 >> f4 >> f5 >> aufZu ) { cout << "Lesen ok" << endl; if( aufZu == "auf" ) { cout << "Text war 'auf'" << endl; } else if( aufZu == "zu" ) { cout << "Text war 'zu'" << endl; } // .. usw. } else cerr << "Fehler beim Lesen" << endl; return 0; }ex.aveal schrieb:
oder kann man dieses "string" einfach in nen char array umwandeln?
kann man mit der Methode c_str(); muss man aber nicht. Wenn Du nur wissen willst, ob es "auf" oder "zu" war, so kannst Du es einfach so machen wie in meinem Vorschlag oben.
Gruß
Wernerverdammt, du bist mein europameister 2008
und vielen dank auch an die anderen für die super schnelle und gute hilfe hier!!! 
aber wie gesagt: für einen anfänger ist die FAQ wirklich nicht oft sehr hilfreich, denn die beispiele, mit denen bestimmte funktionen und methoden beschrieben werden sind oft viel zu komplex und nicht nach dem prinzip "möglichst einfach erklärt", oder: wir lernen c++ einfach nicht nach der besten lernreihenfolge an der hochschule

-
ok .. und hier die Variante für die professionelleren Programmierer:
#include <string> #include <fstream> #include <iostream> using namespace std; namespace status { enum Type { auf, zu }; std::ostream& operator<<( std::ostream& out, Type aufZu ) { switch( aufZu ) { case auf: out << "auf"; break; case zu: out << "zu"; break; default: out << "<???>"; break; } return out; } std::istream& operator>>( std::istream& in, Type& aufZu ) { std::string str; if( in >> str ) { if( str == "auf" ) aufZu = auf; else if( str == "zu" ) aufZu = zu; else in.setstate( std::ios_base::failbit ); // Lesefehler } return in; } } int main() { const char* pDatei = "ini.txt"; float f1, f2, f3, f4, f5; status::Type aufZu; ifstream datei( pDatei ); if( !datei.is_open() ) cerr << "Fehler beim Oeffnen der Datei " << pDatei << endl; if( datei >> f1 >> f2 >> f3 >> f4 >> f5 >> aufZu ) { cout << "Lesen ok; gelesen:" << aufZu << endl; // .. usw. } else cerr << "Fehler beim Lesen" << endl; return 0; }Gruß
Werner
-
ex.aveal schrieb:
oder: wir lernen c++ einfach nicht nach der besten lernreihenfolge an der hochschule

Oder noch drastischer ausgedrückt: Ihr lernt erstmal kein C++ (char*, die C-Stringbibliotheken etc. deuten eindeutig auf C-Programmierung hin). Eigentlich sollte jeder Dozent erschlagen werden für so etwas... (Nichts dagegen das man char* nspricht, aber unter C++ erwarte ich auch erstmal C++...)
cu André
-
std::istream& operator>>( std::istream& in, Type& aufZu ) { std::string str; if( in >> str ) { if( str == "auf" ) aufZu = auf; else if( str == "zu" ) aufZu = zu; else in.setstate( std::ios_base::failbit ); // Lesefehler } return in; } }Schreibt man nach einem Lesefehler nicht in den Stream zurück?