xtp file durchsuchen



  • Habe versucht deinen Code soweit zu ändern damit die Ordner in der selben ebene nicht angezeigt werden.

    vector<string> pfadeende;
            for(vector<string>::iterator i = daten.begin(); i != daten.end(); ++i) {
                if ((*i).find(">") !=string::npos && (*i).find("</") !=string::npos && (*i).find(gesucht)==string::npos )
                {
                    pfadeende.push_back((*i).substr((*i).find("</")+2, (*i).size()));
    
                }
            } 
    
             size_t pfadsize = pfadeende.size();
    		 for(size_t i = 0; i < datsize; i++)
    		   for(size_t b = 0; b < pfadsize; b++){
    
                    {
                        if (daten[i].find(pfadeende.at(b)) == string::npos &&daten[i].find(gesucht)!=string::npos )
                        {
                            daten.erase(daten.begin() + i);
                            --datsize;
                            --i;
                        }
    				}}
    

    leider ohne Erfolg



  • Hi, habe Heute endlich Zeit gefunden weiter zu machen.
    habe einen besseren Ansatz gefunden, um das Problem mit denn Unterordnern zu lösen. Aber auch hier ist ein Denkfehler drin....

    string vergleich;
                    for(size_t i = 0; i < datsize; i++)
    				{
    					//Finden von Unterordnern
    				    if (daten[i].find("<") != string::npos)
                        {
    						vergleich=daten[i].substr(2,daten[i].size());
    
    						 for(size_t b = i; b < datsize; b++)
    						 {
    							if(daten[b].find(vergleich) != string::npos) 
    							{
    								for(size_t c = i; c < b; c++)
    								{
    									daten.erase(daten.begin() + c);
    									--datsize;
    									 --c;
    									 --b;
    									 --i;
    								}
    							}
    							if(daten[b].find(gesucht) != string::npos) break;
    						 } 
                        }
    
                    }
    


  • Du könntest dir Arbeit ersparen, wenn du einen std::stack benutzt. Immer wenn ein öffnendes Tag kommt, wirfst du dieses auf den Stack (push_back). Immmer wenn ein schließendes Tag kommt, machst du ein pop_back. Wenn du das gewünschte Tag gefunden hast, stoppst du und hast automatisch den Pfad im Stack stehen.



  • gute idee jedoch hätte ich dann auch den unterordner mit dem offenen tag drin.

    Beispiel:

    <config>
    <On>
    <ohoh>
    test
    </oho>
    <Master>1234</Maste
    </On>
    </Config>

    Ist der gesuchte Ordner Master dürfte ohoh nicht auftauchen, da es noch davor geschlossen wird. Der letze code von mir geht leider auch noch nicht muß noch ein denkfehler drin sein.



  • Hamster schrieb:

    gute idee jedoch hätte ich dann auch den unterordner mit dem offenen tag drin.

    Beispiel:

    <config>
    <On>
    <ohoh>
    test
    </oho>
    <Master>1234</Maste
    </On>
    </Config>

    Ist der gesuchte Ordner Master dürfte ohoh nicht auftauchen, da es noch davor geschlossen wird. Der letze code von mir geht leider auch noch nicht muß noch ein denkfehler drin sein.

    Wenn man den Schreibfehler ("oho" statt "ohoh") korrigiert, sehe ich das Problem nicht. Durch "</ohoh>" wird "<ohoh>" vom Stapel genommen.



  • hast du es vielleicht so gemeint

    for(size_t b = 0; b < datsize; b++)
    {
    if(daten[b].find("<") != string::npos) 
    {
    	 funde.push_back(i)=daten[b];
    	 for(size_t c = b; c < datsize; c++)
    		{
    		if(daten[c].find(funde.at[i]) != string::npos)
    			{
    			funde.pop_back(i);
    			} 
    		if(daten[c].find(gesucht) == string::npos)break;
    		}
    i++;
    {
    


  • Wenn deine Dateien wirklich nur so ein einfaches Schema haben (es gibt keine leeren Tags, keine Attribute etc.), reicht schon Folgendes:

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <stack>
    using namespace std;
    
    struct Tag
    {
    	string name;
    	string content;
    
    	bool isClosingTag() { return name[0] == '/'; }
    };
    
    istream& operator>>(istream& in, Tag& tag)
    {
    	string buffer;
    	getline(in, buffer, '<');
    	size_t tagClosePos = buffer.find('>');
    	if(tagClosePos == string::npos)
    	{
    		in.setstate(ios::failbit);
    		return in;
    	}
    	tag.name = buffer.substr(0, tagClosePos);
    	tag.content = buffer.substr(tagClosePos + 1);
    	return in;
    }
    
    int main()
    {
    	ifstream in("test.txt");
    	if(!in)
    	{
    		cerr << "Konnte Datei nicht oeffnen." << endl;
    		return -1;
    	}
    	in.ignore(1);	// ignoriere erstes '<'. Eventuell auch noch führende Leerzeilen und <?xml ...> ignorieren
    	stack<Tag> hierarchy;
    	Tag currentTag;
    	while(in >> currentTag)
    	{
    		if(currentTag.isClosingTag())
    			hierarchy.pop();
    		else
    			hierarchy.push(currentTag);
    		if(currentTag.name == "Master")
    			break;
    	}
    
    	while(!hierarchy.empty())
    	{
    		cout << hierarchy.top().name;
    		if(hierarchy.size() > 1)
    			cout << " <- ";
    		hierarchy.pop();
    	}
    }
    

    Getestet mit

    <config>
    <On>foobar
    <ohoh>
    test
    </ohoh>
    <Master>1234</Master>
    </On>
    </config>
    

    ergibt das

    Master <- On <- config
    


  • sauber, Ich sehe schon du hast es ganz anders gemacht als HighLigerBiMBam.
    Würde aber gerne erst mal seinen Code verstehen. Kannst du mir sagen was ich falsch gemacht habe. Ich habe noch Probleme zu verstehen wie es mit den zeigern hier funktioniert und warum ich sie bei pop_down benutzen muß.



  • So läuft. Aber wie ich dafür sorgen, dass bis zum Beginn von Text gelöscht wird.
    Mit vergleich=daten[i].substr(2,daten[i].size()); sorge ich dafür das keine Ordner in der selben ebene angezeigt werden.
    Jedoch geht es nicht wenn der Name erst nach vielen leerzeichen gebinnt. Wie kann ich das umgehen?

    #include "stdafx.h"
    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <string>
    
    using namespace std;
    
    int main()
    {
        ifstream datei;
        datei.open("C:\\test.xtp", ios::in);
        if(!datei)
            cout << "Fehler beim Laden der Datei." << endl;
        else
        {
            vector<string> daten;
    
            while (!datei.eof())
            {
                string str;
                getline(datei, str);
                daten.push_back(str);
            }
            datei.close();
    
            string gesucht;
    
                cout << "||||||||||||||||||||||||||||||||||||||||||||" << endl;
                cout << "Suche nach: ";
              //  cin >> gesucht;
                cout << endl;
    			gesucht ="Master";
    
                    //Entfernen von leeren oder unbrauchbaren Zeilen
                    size_t datsize = daten.size();
                    for(size_t i = 0; i < datsize; i++)
                    {
                        if (daten[i].find(">") == string::npos || daten[i].find("<") == string::npos || daten[i].find("<!") != string::npos)
                        {
                            daten.erase(daten.begin() + i);
                            --datsize;
                            --i;
                        }
                    }
    
    				string vergleich;
                    for(size_t i = 0; i < datsize; i++)
                    {
                        //Finden von Unterordnern
                        if (daten[i].find("<") != string::npos)
                        {
                            vergleich=daten[i].substr(2,daten[i].size());
    
                             for(size_t b = i; b < datsize; b++)
                             {
                                if(daten[b].find(vergleich) != string::npos)
                                {
                                    for(size_t c = i; c < b; c++)
                                    {
                                        daten.erase(daten.begin() + c);
                                        --datsize;
                                         --c;
                                         --b;
                                         --i;
                                    }
                                } //Wenn er unseren gesuchten Ordner gefunden hat werden alle Ordner danach gelöscht
                                if(daten[b].find(gesucht) != string::npos)
    							{ 
    								 for(size_t i = b; i < datsize; i++)
    								  {
    									  daten.erase(daten.begin() + i);
    								      --datsize;
    									  --i;
    								  }
    								break;
    							}
                             }
                        }
    
                    } 
    
    				for(size_t i = 0; i < datsize; i++)
                    {
                        if (daten[i].find("</") != string::npos)
                        {
                            daten.erase(daten.begin() + i);
                            --datsize;
                            --i;
                        }
                    }
    
    				//Ergebnisse werden Presentiert
    				for(size_t i = 0; i < datsize; i++)
    				{
    				cout << daten[i]<<endl;
    				}
    
        }
    
        system("pause");
        return 0;
    }
    


  • Läuft : )

    #include "stdafx.h"
    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <string>
    
    using namespace std;
    
    //Leerzeichen sollen entfernt werden 
    void trim(std::string& strInput)
    {
       // string von VORN durchgehen
       for(size_t i=0; i<strInput.length(); i++)
       {
          if(strInput[i]==' ') 
          {
               strInput.erase(0,1); //erstes Zeichen löschen
               i=-1;        //auf -1 = nächsten Durchlauf 0 (wegen String-Kürzung)
          }
         else break;
       }
    
      /* // string von HINTEN durchgehen
       for(size_t i=strInput.length()-1; i>0 ;i--)
       {
            if(strInput[i]==' ') strInput.erase(i); //letztes Zeichen löschen
            else break;
       }*/
    }
    
    int main()
    {
        ifstream datei;
        datei.open("C:\\test.xtp", ios::in);
        if(!datei)
            cout << "Fehler beim Laden der Datei." << endl;
        else
        {
            vector<string> daten;
    
            while (!datei.eof())
            {
                string str;
                getline(datei, str);
                daten.push_back(str);
            }
            datei.close();
    
            string gesucht;
    
                cout << "||||||||||||||||||||||||||||||||||||||||||||" << endl;
                cout << "Suche nach: ";
              //  cin >> gesucht;
                cout << endl;
    			gesucht ="Master";
    
                    //Entfernen von leeren oder unbrauchbaren Zeilen
                    size_t datsize = daten.size();
                    for(size_t i = 0; i < datsize; i++)
                    {
    					trim(daten[i]);
                        if (daten[i].find(">") == string::npos || daten[i].find("<") == string::npos || daten[i].find("<!") != string::npos)
                        {
                            daten.erase(daten.begin() + i);
                            --datsize;
                            --i;
                        }
                    }
    
    				string vergleich;
                    for(size_t i = 0; i < datsize; i++)
                    {
                        //Finden von Unterordnern
                        if (daten[i].find("<") != string::npos)
                        {
                            vergleich=daten[i].substr(2,daten[i].size());
    
                             for(size_t b = i; b < datsize; b++)
                             {
                                if(daten[b].find(vergleich) != string::npos)
                                {
                                    for(size_t c = i; c < b; c++)
                                    {
                                        daten.erase(daten.begin() + c);
                                        --datsize;
                                         --c;
                                         --b;
                                         --i;
                                    }
                                } //Wenn er unseren gesuchten Ordner gefunden hat werden alle Ordner danach gelöscht
                                if(daten[b].find(gesucht) != string::npos)
    							{ 
    								 for(size_t i = b; i < datsize; i++)
    								  {
    									  daten.erase(daten.begin() + i);
    								      --datsize;
    									  --i;
    								  }
    								break;
    							}
                             }
                        }
    
                    } 
    
    				for(size_t i = 0; i < datsize; i++)
                    {
                        if (daten[i].find("</") != string::npos)
                        {
                            daten.erase(daten.begin() + i);
                            --datsize;
                            --i;
                        }
                    }
    
    				//Ergebnisse werden Presentiert
    				for(size_t i = 0; i < datsize; i++)
    				{
    				cout << daten[i]<<endl;
    				}
    
        }
    
        system("pause");
        return 0;
    }
    


  • boooo ich werde gleich bescheuert....
    warum wird bei

    <?xml?>
    <Offline>
    <ohoh>
    <test>
    </test>
    </ohoh>
    <tes44t>
    </tes44t>
    </Offline>
    <Offline2>
    </Offline2>
    <warum2>
    </warum2>
    <Data-Files>
       <!--Files-->
       <Master</Master>
    <Inertial-Navigation>
    </Inertial-Navigation>
    <bitte nicht>
    

    gesucht wird Master. Alles von <Offline> bis <Offline> wird nicht angezeigt, was auch richtig ist aber warum wird <Offline2> und warum2 angezeigt ????

    habe

    for(size_t c = i; c < b; c++)
                                    {
                                        daten.erase(daten.begin() + i);
                                         --datsize;
                                         --c;
                                         --b;
                                         --i;
    									 break;
                                    }
    

    geändert 🙂



  • Wollte nun zum Finale komme und alles in eine cpp einbauen.
    Jedoch wurde hier schon mal vector benutzt und anders def wie kann ich es umgehen ?



  • Ich würde dir gerne nochmal nahelegen, keine Strings einzulesen, die du dann irgendwie durchsuchst, sondern direkt Tags einzulesen. Dadurch trennst du das Einlesen und Parsen der Tags von dem Aufbauen der Hierarchie, was bei deinem Code durcheinander geht und sich deshalb schneller Fehler einschleichen.

    Um mit <?xml?>, <!--Kommentaren--> und <leerenTags /> klarzukommen, musste ich in dem bereits von mir geposteten Code lediglich zwei Zeilen hinzufügen:

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <stack>
    using namespace std;
    
    struct Tag
    {
        string name;
        string content;
    
        bool isClosingTag() { return name[0] == '/'; }
    	bool isEmptyTag() { return name[0] == '?' || name[0] == '!' || *name.rbegin() == '/'; }
    };
    
    istream& operator>>(istream& in, Tag& tag)
    {
        string buffer;
        getline(in, buffer, '<');
        size_t tagClosePos = buffer.find('>');
        if(tagClosePos == string::npos)
        {
            in.setstate(ios::failbit);
            return in;
        }
        tag.name = buffer.substr(0, tagClosePos);
        tag.content = buffer.substr(tagClosePos + 1);
        return in;
    }
    
    int main()
    {
        ifstream in("test.txt");
        if(!in)
        {
            cerr << "Konnte Datei nicht oeffnen." << endl;
            return -1;
        }
    	{
    		string buffer;
    		getline(in, buffer, '<');	// alle Zeichen bis zum ersten '<' ignorieren
    	}
        stack<Tag> hierarchy;
        Tag currentTag;
        while(in >> currentTag)
        {
    		if(currentTag.isEmptyTag())
    			;	// do nothing
            else if(currentTag.isClosingTag())
                hierarchy.pop();
            else
                hierarchy.push(currentTag);
            if(currentTag.name == "Master")
                break;
        }
    
        while(!hierarchy.empty())
        {
            cout << hierarchy.top().name;
            if(hierarchy.size() > 1)
                cout << " <- ";
            hierarchy.pop();
        }
    }
    

    Wenn dir etwas unklar ist, kannst du gerne fragen.

    Edit: Jetzt können am Anfang der Datei noch beliebig viele Whitespaces stehen.



  • wie schon gesagt habe gerade ein Problem, versuche es in eine Datei einzubinden in der vector neu def wurde.

    Kann ich #include <vector> machen und vector<string> anders schreiben damit es keinen Konflikt gibt ?

    error C2872: 'vector': Mehrdeutiges Symbol



  • lass das using namespace std; weg und nutze überall wo nötig den qualifizierten vector, also:

    #include <vector>
    #include <string>
    #include "deinvector"
    
    std::vector<std::string> blablubb;
    

    genau für/gegen solche konflikte sind namespaces da ....



  • Danke :xmas1: :xmas1:



  • Mach dir doch das Leben leicht und benutze dafür TinyXml. Das kann nicht viel, aber das besonders einfach.
    Es liest dir die Datei in einen passenden Baum ein. Danach kannst du einen Visitor auf den Baum loslassen, der dann für jedes Element aufgerufen wird. Falls du dann ein entsprechendes XML-Element findest gehst du von da nur noch den Baum nach oben und setzt währenddessen den Pfad zusammen. Ist open-source, plattformunabhängig und schnell zu einer Bibliothek gebastelt, falls keine passenden libs für deinen Linker zur verfügung stehen.



  • naja ich habe viel gelernt und nun geht es auch 🙂

    :xmas2:



  • Habe nun <name> w+rde gerne nur name haben
    mit
    daten[i] = daten[i].substr(0, daten[i].length()-1);

    kann ich das letzte zeichen löschen. Aber wie lösche ich das erste. Habe mir gedacht es mit daten[i].beginn() machen aber beginn ist keine länge sondern ein zeiger wenn ich richtig liege.



  • Was sind deiner Meinung nach die Parameter bei substr? (Tipp: pos, length).


Anmelden zum Antworten