Text aus Datei auslesen
-
Hi,
ich habe ein Problem und zwar muss ich einen Text in einer Datei suchen, ist kein Problem, dass bekomme ich auch noch hin.Jetzt soll aber nicht nur diese Zeile ausgeben bei der die Uebereinstimmung vor liegt, sondern eine Zeile vor der Uebereinstimmungen und dann die nachsten 8 nachfolgenden Zeilen auch.
Bsp der gespeicherten Datei:
asdf
ff
aa
as
da
kdla
kdal
ied
kk
pp
ww
ea
rr
yySo, ich suche jetzt nach "da" und die Funktion die ich geschrieben habe, findet dann in der 5. Zeile eine uebereinstimmung. Jetzt moechte ich die Zeile vor "da" ausgeben und die 8 folgenden Zeilen, so dass die Ausgabe in der Konsole dann wie fogt aussieht:
as
da
kdla
kdal
ied
kk
pp
wwIch weiss nicht wie ich angeben kann, welche Zeilen in einer Datei ausgegeben werden sollen. Ich habe mir gedacht ich koennte die Courserposition feststellen lassen, wenn eine Uebereinstimmung zutrifft, jedoch ist dann immer noch das Problem, dass ich von dieser Position eine Zeile nach oben springen muss um anschliessend die naechsten 8 Zeilen auszugeben.
Hoffe ich konnte mein Problem einigermasse erklaeren.
Der eine oder ander fragt sich vllt warum ich nicht gleich nach "as" suche, die Courserposition speichere und dann noch einmal "ww" suche und auch diese Courserposition speichere um diesen Bereich als Block ausgeben lasse. Die Antwort ist einfach, "as" und "ww" sind nicht bekannt, es ist aber bekannt, dass ab "as" nur noch 8 Zeilen bis zu "ww" gibt, die wichtig sind.
Rgds
Coda
-
ja was hällt dich davon ab jede zeile zu speichern und dann von der gefunden zeile z , z-1 bi z+7 auszugeben?
ev. hab ich das problem falsch verstandenlg spjoe
-
Wenn ich wuesste, wie ich feststellen kann in welcher Zeile ich mich befinde waehre das moeglich, jedoch weiss ich bis jetzt nur wie ich die Position des aktuellen Byte-Offset des get-Zeigers relativ zum Dateianfang bekommen kann.
istream.tellg();
wie ich jedoch die Zeile ermitteln kann weiss ich nicht.
Wenn du meinst, dass ich erst alle Zeilen des Dokuments in ein Array einlesen soll und dann die Position im Array ermitteln soll wo die Uebereinstimmung ist und von der dan z-1 bis z+7 ausgeben soll, kann ich gleich sage, dass das zu viel speicher verbraucht.
Rgds
Coda
-
Wenn du in einer Schleife die Zeilen ausliest, kannst du dir doch ganz einfach die Zeilennummer merken...
-
Wie soll ich mir die Zeilennummer merken? er durchsucht das Dokument zeile fuer zeile auf eine Uebereinstuemmung, woher soll ich dann wissen in welcher zeile die Uebereinstiumm war?
Ok, ich koennte einfach einen counter neben her laufen lassen fuer jede Zeile die er ueberprueft, es bleibt jedoch immer noch das Problem wie ich in z.B. Zeile 15 springen kann.
Rgds
Coda
-
das beispiel liest alle zeilen in einen vector, geht diesen dann durch und überprüft wo "da" steht, gibt sogar die zeilennummer aus (du siehst, es ist möglich sich diese zu merken

gibt die zeile vor "da" sowie die folgenden 6 (wie in deinem beispiel) ausstd::vector<std::string> zeilen; while(! file.eof()) { std::string z; // zeile einlesen file >> z; // und in den vector schreiben zeilen.push_back(z); } for(size_t i=0; i<zeilen.size(); ++i) { if(zeilen[i] == "da") { // vorherige zeile ausgeben std::cout << "Zeile " << i << ": " << zeilen[i-1] << std::endl; // die 6 folgenden for(int j=1; j<=6; j++) { std::cout << "Zeile " << i+j << ": " << zeilen[i+j] << std::endl; } } }
-
kein gewähr, dass es läuft,
vergiss die abbruchbedingung nicht (die ich vergessen hab)
und guck, ob die indices stimmen, sonst gibtsn laufzeitfehler
-
Sieht ganz gut aus, jedoch verstehe ich noch nicht so ganz:
vector<string> zeilen;
ich muss die ja noch initialisieren...
test.cpp:11: Fehler: »vector« wurde in diesem Gültigkeitsbereich nicht definiert test.cpp:11: Fehler: expected primary-expression before »>« token test.cpp:11: Fehler: »zeilen« wurde in diesem Gültigkeitsbereich nicht definiertDes Weiteren werden jetzt wirklich alle Zeilen eingelesen und bei einem groesseren Dokument wird das einiges an Speicher verbrauchen, aber wenn es nicht anders geht werde ich es wohl so machen muessen.
Rgds
Coda
-
Hmm also für std::vector brauchst du den HEader <vector>.
Du kannst es auch direkt beim Auslesen machen ... kommt nur darauf an, ob er alle Vorkommen des Strings raussuchen soll, oder nur eine.std::ifstream file_stream("test.dat"); if (!file_stream) throw std::runtime_error("\"test.dat\" could not be opened!"); std::string string_temp; while (std::getline(file_stream, string_temp)) { if (string_temp == "da") { const std::streampos old_pos(file_stream.tellg()); for (std::size_t i(0); i < 6; ++i, std::getline(file_stream, string_temp)) std::cout << string_temp << std::endl; file_stream.seekg(old_pos); } }... wenn er nur einmal finden soll, mach hinter dem file_stream.seekg (wenn du es in eine Funktion auslagerst) dein return oder break (wenn du es nicht in eine Funktion auslagerst).
-
Super, ich danke euch hey & (D)Evil.
Rgds
Coda