Letzten String innerhalb einer Datei auslesen
-
Ich muss innerhalb einer Datei den letzten auftretenden String auslesen. Dazu habe ich eine Funktion geschrieben, die ans Ende der Datei springt und dann solange jeweils ein Zeichen einliest, bis ein Leerzeichen oder Tab gefunden wird. Leider funktioniert das Ganze nicht
. Die Zahlenwerte (Es treten in der einzulesenden Datei nur Zahlen auf) werden korrekt eingelesen. Kommt man an die Stelle des Tab, dann ändert sich der gespeicherte Wert nicht. Tab wird nicht erkannt.Wie kann ich denn auf intelligente und schnelle Weise den letzten String auslesen?
Hier noch der Code der Funktion
/****************************************************************************** * Bestimmung des letzten Strings innerhalb einer Datei ******************************************************************************/ //Öffnen des Eingangs- und des Ausgangsfiles std::ifstream Datei;Datei.open(Filename); //Sicherstellen, dass die Datei existiert if (!Datei) {return 1;} //Variablen unsigned int End_Pos = 0, akt_Pos = 0; char Zeichen = 3; ´ //Bestimmung der Endposition Datei.seekg (0, ios::end); End_Pos = Datei.tellg(); akt_Pos = End_Pos-2; /******************************************************************** * Schleife, die solange läuft, bis wir ein Trennzeichen * (Leerzeichen oder Tab) erwischen *********************************************************************/ do { //ein Zeichen zurück akt_Pos = akt_Pos-1; Datei.seekg(akt_Pos, ios::beg); if (akt_Pos > End_Pos) {return 2;} //Auslesen des aktuellen Zeichens Datei >> Zeichen; } while ((Zeichen != 32) || (Zeichen != 11) ||(Zeichen != 9)); //Nun lesen wir den letzten String aus Datei >> Last_String; return 0;
-
Ich bin mir nicht ganz sicher, ob deine Konstanten stimmen - versuch's doch mal besser mit den Char-Literalen (' ', '\t', '\n') stattdessen. Oder noch besser, du jagst das gelesene Zeichen durch man: isspace.
(PS: Wieso liest du eigentlich deinen String doppelt ein? Du kannst doch in der do-while() Schleife schon alle gelesenen Zeichen im Ausgabestring sammeln)
-
Vielen Dank für Deine Antwort. Habe Deine Vorschläge getestet, komme aber leider nicht weiter. Das Problem liegt nicht in der Abfrage innerhalb der while-Schleife, sondern beim zeichenweisen Einlesen des Textes.
Habe zum Beispiel eine Textdatei mit folgendem Inhalt erzeugt.
311 232 5 7 9
8 1 3 10Im folgenden
erhalte ich diese Werte im char:Pos: 21 ==> char: 0
Pos: 20 ==> char: 1
Pos: 19 ==> char: 3
Pos: 18 ==> char: 3
Pos: 17 ==> char: 1
Pos: 16 ==> char: 1usw.
Ich müsste bei Position 19 bzw. Position 17 eigentlich das White Space bekommen. Kriege ich aber nicht
. Warum auch immer. Dann kann ich natürlich hinten testen soviel ich will.Ich habe keine Ahnung, was ich falsch mache???
-
Ein Blick in die FAQ zeigt uns folgendes Beispiel:
using namespace std; ifstream FileIn("Main.cpp"); if (FileIn) // Falls FileIn gültig ist. { vector<string> Contents; // Container für die einzelnen Zeilen // Solange kein Fehler auftritt und nicht eof for (string ReadString; getline(FileIn, ReadString); ) Contents.push_back(ReadString); // Aktuelle Zeile in den Vektor einfügen // Alle Elemente des Vektors ausgeben. ostream_iterator<string> Out(cout, "\n"); copy(Contents.begin(), Contents.end(), Out); }Daraus machen wir dann einfach
using namespace std; ifstream FileIn("Main.cpp"); if (FileIn) // Falls FileIn gültig ist. { vector<string> Contents; // Container für die einzelnen Zeilen // Solange kein Fehler auftritt und nicht eof for (string ReadString; getline(FileIn, ReadString); ) Contents.push_back(ReadString); // Aktuelle Zeile in den Vektor einfügen cout<<Contents[Contents.size()-1]<<endl; }
// Mist, hab letzte Zeile anstatt letzten String gelesen. Egal, dann musst du einfach die Methode find_last_of(' ') beim letzten VectorElement aufrufen und du hast die Position. Bzw. der letzte String wäre dann
string letzteZeile = Contents[Contents.size()-1]; string letzterString = letzteZeile.substr( letzteZeile.find_last_of(' '), letzteZeile.size() );So ungefähr

-
Ach so meinst du das. In dem Fall solltest du von op>> Abstand nehmen - der hat nämlich die (normalerweise nützliche) Eigenschaft, daß er whitespaces ganz einfach überliest. Als Lösung hast du zwei Möglichkeiten:
//a: get() verwenden: do { //ein Zeichen zurück akt_Pos = akt_Pos-1; Datei.seekg(akt_Pos, ios::beg); if (akt_Pos > End_Pos) {return 2;} //Auslesen des aktuellen Zeichens Datei.get(Zeichen); } while (...); //b: Whitespaces-Skipping ausschalten Datei.unsetf(skipws);/*oder*/Datei>>noskipws; do { //ein Zeichen zurück akt_Pos = akt_Pos-1; Datei.seekg(akt_Pos, ios::beg); if (akt_Pos > End_Pos) {return 2;} //Auslesen des aktuellen Zeichens Datei >> Zeichen; } while (...)
-
@CStoll and Delryn
Vielen Dank für die Antworten. Habe die Variante a) von CStoll verwendet (war am einfachsten *g), jetzt funzt es und ich habe auch noch was gelernt, vieleicht lässt mich mein Chef dann früher nach Hause....
