xtp file durchsuchen



  • so nun versuche ich es nur noch in c++ zu machen. Jedoch stehe ich wieder vor einer Wand.

    er findet bei mir das zeichen nicht, was habe ich falsch gemacht ?

    using namespace std;
    
    void main()
    {
    
        ifstream file;
        char     zeile[1024];
    	size_t found;
    
        file.open("c:\\test.xtp", ios::in);
    
        if (file.good())
        {
            // An den Anfang der Datei springen
            file.seekg(0L, ios::beg);
    
            while (! file.eof())
            {
                // Die Datei zeilenweise auslesen
                file.getline(zeile, 1024);
                cout << zeile << endl;
            }
        }
        else
        {
            cout << "Datei nicht gefunden." << endl;
        }
    
    	string str(zeile);
      found=str.find('<');
      if (found!=string::npos)
    	  cout << "gefunden in: " << int(found) << endl;
    
    system("pause");
    };
    


  • Es wäre günstiger, wenn du die eingelesenen zeilen in einen Vector speicherst, und dafür kein char verwendest. Mit deiner Lösung durchsuchst du nur die zuletzt eingelesene Zeile. benutze konsequent std::string und schieben die Zeilen in den Vector, dann durchsuche den gesamten Vector.

    EDIT: bei einer XML Datei würde in dann allerdings annehemn, dass du in jeder zeile das "<" findest... Eventuell solltest du gleich nach dem gesuchten "value=" suchen.



  • Du kannst das so machen (ungetestet):

    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <string>
    
    using namespace std;
    
    int main()
    {
    	vector<string> daten;			//Enthält alle zeilen aus der Datei
    
    	ifstream datei;					// Datei-Handle
    
    	datei.open("C:\\...", ios::in);	// Öffne Datei aus Parameter
    	if(!datei)
    	{
    		cout << "Die Datei kann nicht geoeffnet werden." << endl;
    	}
    	else
    	{
    		while (!datei.eof())			// Solange noch Daten vorliegen
    		{
    			string str;
    			getline(datei, str);		// Lese eine Zeile
    			daten.push_back(str);		//Zeilen in den Vector schieben
    
    			cout << str << endl;		// Zeige sie auf dem Bildschirm
    		}
    		datei.close();					// Datei wieder schließen
    
    		//mache etwas mit den Daten!!!!
    
    		for(vector<string>::iterator i = daten.begin(); i != daten.end(); ++i) {
    			size_t found = (*i).find("<");
    			if (found!=string::npos)
    				cout << "Der String wurde gefunden an Position: " << static_cast<int>(found) << endl;
    			//mache was du willst
    		}
    	}
    
    	cin.get();
    	return 0;
    }
    


  • ich hoffe ich habe deinen code richtig verstanden. ( wäre nie drauf gekommen es so zu machen )

    -daten.at(i) geht leider nicht.
    - und str.substr (found) kann ich es nicht so einstellen das es nur bis zu found2 liest. lg und danke nochmal

    vector<string>  pfade;
    		string pfad;
    
            for(vector<string>::iterator i = daten.begin(); i != daten.end(); ++i) {
                size_t found = (*i).find("<");
                if (found!=string::npos)
    			{
    				for(vector<string>::iterator b = daten.at(i); b != daten.end(); ++b)
    				{
    					size_t found2 = (*b).find(">");
    						  if (found2!=string::npos)  pfad = str.substr (found);/*Nur bis found2*/  pfade.push_back(pfad); 
    				}
                    cout << "Der String wurde gefunden an Position: " << static_cast<int>(found) << endl;
    			}
    


  • Du brauchst den Vector nicht zweimal durchlaufen.

    vector<string> pfade;        
    
    for(vector<string>::iterator i = daten.begin(); i != daten.end(); ++i) {
                size_t found = (*i).find("<");
                size_t found2 = (*i).find(">");
                if (found!=string::npos)
                    cout << "Der String < wurde gefunden an Position: " << static_cast<int>(found) << endl;
    
                if (found2!=string::npos)
                    cout << "Der String > wurde gefunden an Position: " << static_cast<int>(found2) << endl;
                //mache was du willst
    
                string pfad;
                pfad = (*i).substr(found, found2 - found);
                pfade.push_back(pfad);
    
            } //hier nach mit pfaden machen was du willst
    

    EDIT: Da fehlt noch einige Sicherheit und du musst schauen ob das Ergebnis = der Erwartung entspricht, eventuell habe ich auch einen fehler drinne (ungetestet).
    EDIT: Man kann natürlich die letzten 3 zeieln auch so schreiben:

    pfade.push_back((*i).substr(found, found2 - found));
    

    oder auch alles in der klammer in eine Zeile o.O

    pfade.push_back((*i).substr((*i).find("<"), (*i).find(">") - (*i).find("<")));
    

    fehlt dann aber nur noch ein:

    if ((*i).find(">") !=string::npos && (*i).find("<") !=string::npos)
    

    So nun bin ich Amok gelaufen!



  • wuw sry die letzen zwei dinger sind noch lange nicht in meiner ligga ( leider )

    jedoch bekomme ich einen speicherfehler: in der zeile

    pfad = (*i).substr(found, found2 - found);
    

    bin mir nicht sicher woran es liegen könnte



  • keine Prüfung von found und found2 auf string::npos siehe letzter codeblock.

    if ((*i).find(">") !=string::npos && (*i).find("<") !=string::npos)
    

    ist das selbe wie:

    if (found !=string::npos && found2 !=string::npos)
    


  • Getestet:

    #include <iostream> 
    #include <fstream> 
    #include <vector> 
    #include <string> 
    
    using namespace std; 
    
    int main() 
    { 
        vector<string> daten;            //Enthält alle zeilen aus der Datei 
    
        ifstream datei;                    // Datei-Handle 
    
        datei.open("C:\\test.txt", ios::in);    // Öffne Datei aus Parameter 
        if(!datei) 
        { 
            cout << "Die Datei kann nicht geoeffnet werden." << endl; 
        } 
        else 
        { 
            while (!datei.eof())            // Solange noch Daten vorliegen 
            { 
                string str; 
                getline(datei, str);        // Lese eine Zeile 
                daten.push_back(str);        //Zeilen in den Vector schieben 
            } 
            datei.close();                    // Datei wieder schließen 
    
            //mache etwas mit den Daten!!!! 
    
    		vector<string> pfade;
    
    		for(vector<string>::iterator i = daten.begin(); i != daten.end(); ++i) { 
    			if ((*i).find(">") !=string::npos && (*i).find("<") !=string::npos)
    				pfade.push_back((*i).substr((*i).find("<"), (*i).find(">") - (*i).find("<") + 1)); 
            } 
    		//hier mit pfaden machen was du willst
    
    		for(vector<string>::iterator i = pfade.begin(); i != pfade.end(); ++i) { 
    			cout << "Pfad: " << (*i).c_str() << endl;
    		}
    		/////////////////////////////////////////////
        } 
    
        cin.get(); 
        return 0; 
    }
    


  • genial, ich habe ein schlechtes Gewissen. Du hast den ganzen code in c++ für mich überschrieben. Und finde ihn 100 mal besser als meinen c code. Alles greift genau in einer über. Machst du das Beruflich ?



  • Hamster schrieb:

    genial, ich habe ein schlechtes Gewissen. Du hast den ganzen code in c++ für mich überschrieben. Und finde ihn 100 mal besser als meinen c code. Alles greift genau in einer über. Machst du das Beruflich ?

    Ist mehr als Hobby entstanden, ich begeistere mich dabei aber auch für andere Sprachen.



  • eine kleinigkeit habe ich noch.

    Wenn ich rausfinden will zwischen welchen ordnern bein gesuchter ordner liegt.

    for(vector<string>::iterator i = daten.begin(); i != daten.end(); ++i) {
                if ((*i).find(">") !=string::npos && (*i).find("<") !=string::npos)
                    pfade.push_back((*i).substr((*i).find("<"), (*i).find(">") - (*i).find("<") + 1));
    			if((*i).find("<Data-Files>")!=-1)posges=(*i).find("<Data-Files>");
    

    schaut nicht besonders elegant aus. finde so aber denn gesuchten ordner.

    Ich könnte jetzt:

    string vergleich;
    int pos1;
    cout<<"Der gesuchte liegt in: "<<endl;
    for(int i=0;i<str.size();i++)
    {
    vergleich = pfade.at(i);
    pos1=str.find(vergleich);
    cout <<pos1<<endl;
    }
    

    (( schaut alles nicht besonders gut aus))

    ich habe hier ein Problem da



  • Was ist str? Was willst du erreichen? Wenn überhaupt gibst du momentan aus, an welcher Stelle im String der gesuchte Wert gefunden wurde.

    for(int i = 0; i < pfade.size(); i++){
        if(pfade.at(i).find("Zu vergleichender string") != string::npos)
            cout << "Der gesuchte liegt in: " << i << endl;
    }
    

    Willst du das machen?



  • nun ja ich habe nun alle ordner.
    Und nun will ich wissen welcher Ordner ( gesuchter string ) welche überordner hat.
    Bsp:

    <Config>
    </Offline>
    <Inertial-Navigation>
    <Master>gesuchterstring</Master>
    </Inertial-Navigation>
    <Data-Files>
    </Data-Files>
    </Config>

    jetzt wollte ich so rangehen. nehme pfade.at(i) berechne seine position. Ändere diesen String zu ( füge die ersten beiden zeichen dazu ) </ und suche nach diesem ordner. Ist der gesuchte string größer als der erste gefundene string aber kleiner als zweite ( der manipulierte) dann ist der gesuchte ordner ein unterordner vom ersten.

    in c habe ich es mit schleife und array ganz einfach gelöst. Hier würde ich genau so rangehen. Erscheint mir aber umständlicher.

    lg



  • Was soll denn das Ergebnis es ganzen sein? Ich suche nach "gesuchterstring" und erhalte? <Inertial-Navigation> oder <Config>?

    Vielleicht hilft einfach ein kleines funktionierendes Fragment der XML.



  • jap fast ich würde.

    Config und dann Inertial-Navigation
    ( mit anderen worten der gesuchte string liegt in Config und dann in Inertial-Navigation )

    oder besser ich würde wissen an welcher position. Also ich würde wissen das pfade.at(3) und pfade.at(7) // Als Beispiel

    denkst du ich sollte es so machen. Also String ändern zu </... und dann danach suchen und vergleichen ?
    lg



  • Um dir das Thema vector näher zu bringen schreibe ich dir es nochmal hin. Du solltest dich damit beschäftigen. Damit du es nachvollziehen kannst habe ich es ohne Klassen oder Strukturen gehalten (eventuell auch unsauber programmiert). Das Ergebnis des ganzen sind alle übergeordneten Einträge des gesuchten "Strings", auch wenn dieser mehrfach gefunden wurde. Dazu habe ich einen mehrdimensionalen Vector benutzt, dessen Elemente auch Vectoren sind. Viel Spaß!

    #include <iostream> 
    #include <fstream> 
    #include <vector> 
    #include <string> 
    
    using namespace std; 
    
    int main() 
    { 
        vector<string> daten;            //Enthält alle zeilen aus der Datei 
    
        ifstream datei;                    // Datei-Handle 
    
        datei.open("C:\\test.txt", ios::in);    // Öffne Datei aus Parameter 
        if(!datei) 
        { 
            cout << "Die Datei kann nicht geoeffnet werden." << endl; 
        } 
        else 
        { 
            while (!datei.eof())            // Solange noch Daten vorliegen 
            { 
                string str; 
                getline(datei, str);        // Lese eine Zeile 
                daten.push_back(str);        //Zeilen in den Vector schieben 
            } 
            datei.close();                    // Datei wieder schließen 
    
            //mache etwas mit den Daten!!!! 
    
            vector<string> pfade;
    		vector<int> tiefe;
            for(vector<string>::iterator i = daten.begin(); i != daten.end(); ++i) { 
                if ((*i).find(">") !=string::npos && (*i).find("<") !=string::npos)
    			{
                    pfade.push_back((*i).substr((*i).find("<"), (*i).size()));
    				tiefe.push_back((*i).find("<"));
    			}
            } 
            //hier mit pfaden machen was du willst 
    
    		string gesucht = "string";
    
    		vector<int> funde;
    		for(int i = 0; i < pfade.size(); i++){
    			if(pfade.at(i).find(gesucht) != string::npos)
    			{
    				funde.push_back(i);
    			}
    		}
    
    		//Wir haben den String ein/kein oder mehrere male gefunden
    		vector< vector<string> > unterordner;
    		for(vector<int>::iterator i = funde.begin(); i != funde.end(); ++i){
    			int fund = *i;
    
    			vector<string> ordner;
    			ordner.push_back(pfade.at(fund)); //Gesuchter String in Vector schieben
    			//Alle übergeordneten Ordner hinter den gesuchten einfügen
    			while (fund > 0 && tiefe.at(fund) > tiefe.at(fund - 1))
    			{
    				--fund;
    				ordner.push_back(pfade.at(fund));
    			};
    
    			 //ordner vector in vector schieben
    			unterordner.push_back(ordner);
    		}
    
    		//in Unterordner sind jetzt ein/keine oder mehrere Vectoren die an erster Position den gesuchte´n
    		//String enthalten und an den weiteren Positionen die übergeortneten Ordner
    
    		//Ausgabe des Ergebnisses
    		for(vector< vector<string> >::iterator i = unterordner.begin(); i != unterordner.end(); ++i){
    			for (vector<string>::iterator pos = (*i).begin(); pos != (*i).end(); ++pos)
    				cout << (*pos).c_str() << endl;
    			cout << endl;
    		}
    
            ///////////////////////////////////////////// 
        } 
    
        cin.get(); 
        return 0; 
    }
    

    Testdatei sieht so aus:

    <Config>  
    	<Inertial-Navigation> 
    		<Master>string</Master> 
    	</Inertial-Navigation> 
    	<Data-Files> 
    	</Data-Files> 
    </Config>
    

    Ausgabe ist:

    <Master>string</Master>
    <Inertial-Navigation> 
    <Config>
    

    PS: Bisheriger Code wurde entsprechend der Anforderung umgestaltet. Harte Kost für einen STL-Anfänger.



  • habe bis jetzt immer mit einem c buch gearbeitet werde mir auf jeden ein c++ buch besorgen.

    Habe deinen Code getestet. Bei deinem Beispiel geht es. Versuche ich jedoch.

    <Ordner1>
     <Ordner2>
      <Ordner3>
      </Ordner3>
      <gesucht>
        <X>2</X>
      </gesucht>
     </Ordner2>
    </Ordner1>
    

    bekomme ich als resultat

    <gesucht>
    
    </gesucht>
    

    jedoch ist gesucht ein unterordner von Ordner1 und Ordner2 😕



  • //Alle übergeordneten Ordner hinter den gesuchten einfügen 
    while (fund > 0 && tiefe.at(fund) > tiefe.at(fund - 1))
    

    hier liegt das Problem muss >= sein, da die Ordner gleiche Länge haben konnte er diese darüberliegenden nicht finden.



  • ich glaube daran liegt es nicht , bekomme speicherfehler 😞



  • Hamster schrieb:

    ich glaube daran liegt es nicht , bekomme speicherfehler 😞

    Ja wenn du es vorne Einsetzt... Ich empfehle dir C++ Primer.


Anmelden zum Antworten