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
    yy

    So, 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
    ww

    Ich 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 verstanden

    lg 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) aus

    std::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 definiert
    

    Des 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


Anmelden zum Antworten