xtp file durchsuchen



  • fund ist die stelle im Vector und tiefe enthält die leerzeichen/tabs der Zeile (das eingerückte) dies habe ich über str.find("<") gemacht.

    Das: && tiefe.at(fund) >= 0 ergibt übrigends keinen Sinn weil tiefe immer >=0 ist somit kann mans weglassen...

    Benutze mal diese Datei zum testen, dann siehst du dass auf dich noch Arbeit zukommt:

    <ordner1> 
     <ordner2> 
      <ordner3> 
       <ordner4> 
       </ordner4> 
      </ordner3> 
      <gesuchter> 
      </gesuchter> 
     </ordner2> 
    </ordner1>
    <ordner1> 
     <ordner2> 
      <ordner3> 
       <ordner4> 
        <ordner5>
        </ordner5> 
       </ordner4> 
      </ordner3> 
      <gesuchter> 
      </gesuchter> 
     </ordner2> 
    </ordner1>
    


  • Sry ich verstehe nicht was genau der Sinn von tiefe ist.
    Kann ich nicht nachdem ich alle Ordner habe. In etwa so rangehen:
    -schleife von Ordner.anfang bis Ordner.ende
    - Ordner.at(1) gibt mir einen ordner wieder nachdem ich nochmal suche. Das Ergebnis
    Müsste der </ordner> sein. Ist der gefundene Wert ( seine Position ) größer als funde, dann ist der gesuchte string ein Unterordner davon. Und da ich von Anfang bis Ende gehe müsste es sich doch automatisch sortieren.
    Sry ich glaube ich denke noch zu einfach um deinen Ansatz richtig zu erfassen.



  • Die ordner in Vector ordner haben keine tiefe mehr, da diese ein Substring der Datei sind. Sicher kannst du es auch so machen wie du es beschreibst, dann müsstest du aber auch weitere Teile des Codes ändern umschreiben.

    Aber das was du gerade schilderst kann man jetzt trotzdem machen. Nur dass die tiefe halt in einem anderen Vector als ordner gespeichert ist. Ich würde dir aber empfehlen, den Code so zu ändern, dass er 100% funktioniert und dann diesen verbessern vereinfachen.

    Als gute Übung könntest du hier später Klassen verwenden!

    Damit der Code mit meiner Beispieldatei funktioniert musst du nicht mehr viel ändern. Letztlich macht das was ich bei mir seit Tagen stehen habe nichts anderes als das was du erwähnt hast. Nur versuch du es mal umzusetzen! Dazu müssen nur Änderungen vor/innerhalb der Schleife durchgeführt werden und das Ergebnis meiner Testdatei ist:

    <gesuchter>
    <ordner2>
    <ordner1>
    
    <gesuchter>
    <ordner2>
    <ordner1>
    

    Zwei Funde mit dessen Unterordnern.



  • ok, der Schatz liegt in dieser schleife vergraben. Leider habe ich keine Schaufel. Könntest du mir bitte mit worten erklären was genau in der schleife passiert. Da ich denn Fehler einfach nicht sehe ( ich habe noch nicht mal eine Vermutung ) ... Nur Wälder kein Bäume...



  • Hamster schrieb:

    ok, der Schatz liegt in dieser schleife vergraben. Leider habe ich keine Schaufel. Könntest du mir bitte mit worten erklären was genau in der schleife passiert. Da ich denn Fehler einfach nicht sehe ( ich habe noch nicht mal eine Vermutung ) ... Nur Wälder kein Bäume...

    In den Schleife werden die Unterordner ermittelt und in den Ergebnisvector geschoben. Nur leider passiert dies nicht so wie du das möchtest.

    Zum einen wird die Schleife nicht beendet, wenn die tiefe 0 erreicht ist.
    Zum andern stimmt die If-Abfrage nicht. Sie müsste ungefähr so aussehen tiefe.at(count) < tiefe.at(fund). Aber dafür benötigen wir noch eine Zählvariable die mit fund initialisiert wird. Und als Tipp: do while...



  • vector<int>::iterator count = funde.begin();
            for(vector<int>::iterator i = funde.begin(); i != funde.end(); ++i){
                int fund = *i;
    		    ++count;
    			int cout =*count;
    
                vector<string> ordner;
                ordner.push_back(pfade.at(fund)); //Gesuchter String in Vector schieben
                //Alle übergeordneten Ordner hinter den gesuchten einfügen
    
               do
                {
    				--fund;
    				if(tiefe.at(cout) < tiefe.at(fund)) //Zusatz verhindert selbe Ebene
                    ordner.push_back(pfade.at(fund));
                } while (fund > 0 && tiefe.at(fund) >= tiefe.at(fund - 1)&&tiefe.at(fund)>0);
    

    was ist der Sinn vom count ? 😕



  • So hättest du es machen können/war es gemeint. Man kann hier noch einiges vereinfachen/ändern. Wenn du möchtest poste ich dir nochmal alles komplett und zwar deutlich verändert.

    vector< vector<string> > unterordner;
    for(vector<int>::iterator i = funde.begin(); i != funde.end(); ++i)
    {
    	int fund = *i;
        int count = fund;
    
    	vector<string> ordner;
    	ordner.push_back(pfade.at(fund));
    	if(fund > 0) //verhindert Zugriffsfehler
    	{
    		do
    		{
    			--count;
    			if(tiefe.at(count) < tiefe.at(fund))
    				ordner.push_back(pfade.at(fund));
    		}while (count > 0 && tiefe.at(count) != 0);
    	}
    	unterordner.push_back(ordner); 
    }
    


  • Wenn du möchtest poste ich dir nochmal alles komplett und zwar deutlich verändert.
    

    👍 👍 👍 👍 🙄



  • Ok viel spaß.

    #include <iostream> 
    #include <fstream> 
    #include <vector> 
    #include <string> 
    
    using namespace std; 
    
    int main()
    { 
        ifstream datei;
        datei.open("C:\\test.txt", 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;
    		const string beenden = "quit";
    
    		do
    		{
    			cout << "||||||||||||||||||||||||||||||||||||||||||||" << endl;
    			cout << "Zum Beenden \"" + beenden + "\" schreiben." << endl;
    			cout << "Suche nach: ";
    			cin >> gesucht;
    			cout << endl;
    
    			if(gesucht != beenden)
    			{
    				//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;
    					}
    				}
    
    				//Suchen und speichern der Funde
    				vector<int> funde;
    				for(size_t i = 0; i < datsize; i++) 
    					if(daten[i].find(gesucht) != string::npos)
    						funde.push_back(i);
    
    				//Finden der übergeordneten Ordner
    				vector< vector<string> > ueberordner;
    				for(vector<int>::iterator i = funde.begin(); i != funde.end(); ++i)
    				{
    					int count = *i;
    
    					vector<string> ordner;
    					ordner.push_back(daten[*i]);
    					if(*i > 0)
    					{
    						do
    						{
    							--count;
    							if(daten[count].find("<") < daten[*i].find("<"))
    								ordner.push_back(daten[count]);
    						}while (count > 0 && daten[count].find("<") != 0);
    					}
    					ueberordner.push_back(ordner); 
    				}
    
    				//Ausgabe
    				for(vector< vector<string> >::iterator i = ueberordner.begin(); i != ueberordner.end(); ++i)
    				{ 
    					cout << "Gefunden: ";
    					for (vector<string>::iterator pos = (*i).begin(); pos != (*i).end(); ++pos) 
    						cout << (*pos).substr((*pos).find("<"), (*pos).size()).c_str() << endl; 
    					cout << endl; 
    				}
    			}
    		} while(gesucht != beenden);
        } 
    
    	system("pause");
        return 0; 
    }
    


  • danke nochmal 😃



  • 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;
    }
    

Anmelden zum Antworten