Wert nach einem bestimmten Satz in einer txt datei suchen



  • Ich weiss wie ich die Datei öffne und auch dem String suche.

    Darum bin ich davon ausgegangen dass das nicht das Problem ist 😉

    Ich mag jetzt kein Beispiel machen.

    Wenn die Datei relativ klein ist (<30kB) dann würde ich sie mit einem Stream (siehe: http://www.cplusplus.com/reference/fstream/ifstream/) in einem Rutsch in einen std::string einlesen (siehe: http://www.cplusplus.com/reference/string/string/?kw=string) und dann die Suche
    mit den find Funktionen und das extrahieren mit substr machen.

    Versuche es mal, das Erfolgserlebnis ist grösser wenn Du es selbst machst 😉



  • Die Datei hat jetzt 47kb und die Größe ist nicht immer gleich.



  • Ist das nicht ein WTF-in-the-making? Das Format ist doch offensichtlich XML, also sollte das auch mit einem XML-Parser gemacht werden.



  • Ich weiss nur ungefähr was ein XML-Parser ist und würde doch gerne ein eigenes in C++ Programm haben das den Text Zeile für Zeile liest und dann entsprechend meinen Anweisungen Filtert.



  • Die Datei hat jetzt 47kb und die Größe ist nicht immer gleich.

    Detail!!! lies die Datei in einem Rutsch ein

    3 Minuten nach meinem Post Deine Antwort.... Du hast die verlinkten Seiten nicht mal angeschaut 😞

    Ist das nicht ein WTF-in-the-making? Das Format ist doch offensichtlich XML, also sollte das auch mit einem XML-Parser gemacht werden.

    Ich glaube das ist ein (IMHO gutes und nötiges) Übungsprojekt 😉



  • Ich immer noch auf den Seiten die du vorgeschlagen hast. Habe nur schnell mal auf deinem Post geantwortet.



  • Tja ich komme nicht weiter.
    Das habe ich bis jetzt geschafft.

    #include <fstream>
    using namespace std;
    
    int main()
    {
        fstream f;
        ifstream h;
        string s;
        f.open("1.txt", ios::out);
        getline(h, s);
        if(s == "MOVE FlowID"){
    
        }
        f.close();
    }
    

  • Mod

    Gib deinen Bezeichnern mal aussagekräftige Namen, dann fallen dir hoffentlich schon ein paar Fehler auf.

    Programmier nicht durch zusammenkopieren und verändern von Beispielen. Besonders nicht, wenn du sie nicht verstehst.

    c.rackwitz schrieb:

    Wenn du selber Code schreibst, musst du ihn auch verstehen. Code ist kein Haufen von wahllos zusammengeschmissenen Buchstaben und Zeichen, Code ist Logik pur. Du musst genau wissen, warum du wo und welches Zeichen setzt.

    Guck dir auch noch mal die von weicher verlinkten Seiten an, ob dein Vergleich wirklich das ist, was du möchtest.



  • Ich habe die Seiten seit gestern auf als ich das ge-googlet habe.
    Werde aber nicht ganz schlau daraus weil mir Fundamentales Wissen fehlt.
    Ich habe die Fehler gesehen....ups.
    Könntet ihr mir zu meiner Frage helfen?



  • Ich versuche mal Dir zu zeigen wie man diese Doku liest 😉

    - Öffne die Site http://www.cplusplus.com/reference/fstream/
    - Da siehst Du: Class templates und darunter Classes
    - Du willst einlesen, also input file stream == ifstream
    - Click auf ifstream
    - Du weisst jetzt ifstream ist eine Klasse zum einlesen von Files
    - Jede Klasse hat einen constructor (ctor) und einen destruktor (dtor)
    - Also scrollst Du runter bis zu den Public member functions und siehst dort (constructor)
    - Click auf (constructor)
    - Dann liest Du die Bemerkungen (1)..(4) bis Du alles verstanden hast
    - Dann scrollst Du ganz nach unten und schaust Dir das Example an
    - Jetzt kannst Du das Example als Konsolenprogramm eintippen, kompilieren und mit dem Debugger im Einzelschritt ausführen und bei jedem Schritt genau verfolgen was passiert.
    - Jetzt gehst Du wieder auf die Site http://www.cplusplus.com/reference/fstream/ und gibst oben im Suchfeld getline ein
    - Jetzt baust Du das Beispiel so um, dass getline verwendet wird.
    - Und wieder, kompilieren und Debuggen.

    Wenn Du soweit bist und Deine Datei in Zeilen einlesen konntest dann meldest Du Dich wieder.



  • weicher schrieb:

    Ist das nicht ein WTF-in-the-making? Das Format ist doch offensichtlich XML, also sollte das auch mit einem XML-Parser gemacht werden.

    Ich glaube das ist ein (IMHO gutes und nötiges) Übungsprojekt 😉

    Das bezweifle ich, denn das sieht doch arg konkret aus. Zur Übung könnte man auch ein anderes Format nehmen.

    Ich hab halt so meine Erfahrungen mit offensichtlich ad-hoc zusammengestöpselten Parsern für XML-basierte Formate gemacht, die dann plötzlich streiken, wenn irgendwelche völlig unschuldigen Umformatierungen gemacht werden.



  • Das bezweifle ich, denn das sieht doch arg konkret aus. Zur Übung könnte man auch ein anderes Format nehmen.

    Ich weiss nicht was das werden soll. Das kann nur "BoomC" beantworten.

    Ich sehe nur, dass man damit die iostreams, strings und wenn es dann weitergeht auch noch den vector und die umwandlung von string in float oder double begreifen könnte.



  • Hier eine einfache Lösung, wie du alle Datensätze einlesen kannst. Was hälst du davon, BoomC?

    #include <iostream>
    #include <fstream>
    #include <map>
    #include <string>
    #include <vector>
    #include <utility>
    using namespace std;
    
    template<typename T>
    T einlesen( istream& in )
    {
    	for(T x;;)
    	{
    		if( in >> x )
    		{
    			return x;
    		}
    		else
    		{
    			in.clear();
    			in.ignore( 1 );
    		}
    	}
    }
    
    int main()
    {
    	ifstream file( "test.txt" );
    	map< unsigned, vector<pair<float,float>> > records;
    
    	for( ; file; )
    	{
    		string  zeilenanfang;
    		file >> zeilenanfang;
    
    		if( zeilenanfang == "<MOVE" ) // Datensatz kommt nun
    		{
    			unsigned key = einlesen<unsigned>( file ); // Schlüssel einlesen
    			float x      = einlesen<float>   ( file ); // X einlesen
    			float y      = einlesen<float>   ( file ); // Y einlesen
    
    			if( file )
    				records[ key ].push_back( make_pair(x,y) ); // Datensatz speichern
    		}
    	}
    
    	// Testausgaben
    	for( map< unsigned, vector<pair<float,float>> >::iterator it=records.begin(); it!=records.end(); ++it)
    	{
    		for( vector<pair<float,float>>::iterator iter=it->second.begin(); iter!=it->second.end(); ++iter)
    		{
    			cout << it->first << " ==> " << "X=" << iter->first << " und Y= " << iter->second << '\n';
    		}
    	}
    }
    


  • So....zur XML frage!
    Die Files sind wirklich sehr verschieden!
    Es gibt etwa 300-400 arten davon.
    Wenn ich es schaffe diese Datei zu filtern dann könnte ich mit dem Wissen und die jeweiligen bedingungen immer mein eigenes Prog machen.



  • Ich bekomme diese Fehlermeldung:

    'xml.exe' (Win32): Loaded 'C:\Users\Boom\Documents\Visual Studio 2012\Projects\xml\xml\xml.exe'. Symbols loaded.
    'xml.exe' (Win32): Loaded 'C:\Windows\SysWOW64\ntdll.dll'. Cannot find or open the PDB file.
    'xml.exe' (Win32): Loaded 'C:\Windows\SysWOW64\kernel32.dll'. Cannot find or open the PDB file.
    'xml.exe' (Win32): Loaded 'C:\Windows\SysWOW64\KernelBase.dll'. Cannot find or open the PDB file.
    'xml.exe' (Win32): Loaded 'C:\Windows\SysWOW64\msvcp110d.dll'. Symbols loaded.
    'xml.exe' (Win32): Loaded 'C:\Windows\SysWOW64\msvcr110d.dll'. Symbols loaded.
    The program '[2304] xml.exe' has exited with code 0 (0x0).

    Bis jetzt habe ich mir so geholfen das ich das Prog Direkt erstellt habe nun wollte ich mal Step by Step Debugen.


  • Mod



  • Habe es schon gegooglet und eine menge ausprobiert, der Fehler ist immer noch da.
    Zu viel wollte ich jedoch nicht ändern. Dacht das Direkt weiss was Sache ist.



  • Hallo BoomC,

    BoomC schrieb:

    Ich weiss nur ungefähr was ein XML-Parser ist und würde doch gerne ein eigenes in C++ Programm haben das den Text Zeile für Zeile liest und dann entsprechend meinen Anweisungen Filtert.

    .. nur soviel: man liest nicht 'Zeile bei Zeile', und schon gar nicht bei einer XML-Datei, weil diese nämlich u.U. gar keine Zeilen hat.

    Es ist schon zu empfehlen, einen einfachen Parser zu nutzen - z.B. TinyXML.
    Mit C++-Standardmitteln sähe es z.B. so aus:

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <limits> // std::numeric_limits<>
    
    int main()
    {
        using namespace std;
        ifstream in("datei.xml"); // <== hier richtigen Dateinamen eintragen
        if( !in.is_open() )
        {
            cerr << "Fehler beim Oeffnen der Datei" << endl;
            return -2;
        }
        while( in ) // solange kein (Lese-)Fehler aufgetreten ist
        {
            // überlese alles bis '<' und "MOVE"
            for( string token; in.ignore( std::numeric_limits< std::streamsize >::max(), '<' ) >> token && token != "MOVE"; )
                ;
    
            // --   hier geht's los; Attribute lesen ...
            int x, y;
            int xy_gelesen = 0;
            for( string attribut; xy_gelesen != 3 && getline( in >> ws, attribut, '=' ); ) // Lese zunächst den Namen des Attributs -> 'attribut'
            {
                char hk; // "-Zeichen
                if( attribut == "X" )
                {
                    if( !(in >> hk >> x >> hk) )
                        break; // Lesefehler
                    xy_gelesen |= 1;
                }
                else if( attribut == "Y" )
                {
                    if( !(in >> hk >> y >> hk) )
                        break; // Lesefehler
                    xy_gelesen |= 2;
                }
                else
                    (in >> hk).ignore( std::numeric_limits< std::streamsize >::max(), '"' ); // überspringe andere Attribute
            }
            if( xy_gelesen == 3 )
                cout << "x=" << x << " y=" << y << endl;
        }
        return 0;
    }
    

    Mit tinyxml2 wird es übersichtlicher und sicherer:

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <tinyxml2.h>
    
    void parse( const tinyxml2::XMLNode& parent )
    {
        using namespace std;
        using namespace tinyxml2;
        for( const XMLNode* node = parent.FirstChild(); node; node = node->NextSibling() )
        {
            const XMLElement* elem = node->ToElement();
            if( !elem )
                continue;
            if( string(elem->Name()) == "MOVE" )
            {
                int x = elem->IntAttribute( "X" );
                int y = elem->IntAttribute( "Y" );
                cout << "x=" << x << " y=" << y << endl;
            }
            else
                parse( *elem );
        }
    }
    
    int main()
    {
        using namespace std;
        using namespace tinyxml2;
        XMLDocument doc;
        if( doc.LoadFile("datei.xml") != 0 )
        {
            cerr << "Fehler beim Oeffnen der Datei" << endl;
            return -2;
        }
        parse( doc );
        return 0;
    }
    

    probier's einfach aus.

    Gruß
    Werner



  • SeppJ schrieb:

    c.rackwitz schrieb:

    Wenn du selber Code schreibst, musst du ihn auch verstehen. Code ist kein Haufen von wahllos zusammengeschmissenen Buchstaben und Zeichen, Code ist Logik pur. Du musst genau wissen, warum du wo und welches Zeichen setzt.

    Was für ein Quatsch. Verständnis ist ein überbewertetes Konzept.

    Back in the good old days-- the "Golden Era" of computers-- it was easy to separate the men from the boys (sometimes called "Real Men" and "Quiche Eaters" in the literature). During this period, the Real Men were the ones who understood computer programming, and the Quiche Eaters were the ones who didn't.
    ...

    http://www.pbm.com/~lindahl/real.programmers.html

    Nach all den Jahren immer noch eine Freude das zu lesen.

    EDIT:
    Das zweite, gelöschte Zitat hatte nur wenig mit dem Thema zu tun.


  • Mod

    Das heißt, du nennt dich selbst einen Quiche Eater? 😮


Anmelden zum Antworten