xtp file durchsuchen
-
ok, nun werden nur noch die <...> ordner angezeigt
for(int i = 0; i < pfade.size(); i++){ if(pfade.at(i).find(gesucht) != string::npos &&pfade.at(i).find("</")== string::npos) { funde.push_back(i); } }jedoch verstehe ich noch nicht, warum er keine anderen ordner mehr anzeigt, wenn ich ordner4 einfüge.
Es muß etwas mit fund zu tun haben.Jedoch verstehe ich nicht wie der fehler zustande kommt.
-
Lass dir doch mal ausgeben, was in fund liegt. Ich denke nicht das dort der Fehler bei dir ist.
So wie du es hast sollte nur <gesucht> als String enthalten sein.
Edit: Schau dir die Schleife näher an!
while (fund > 0 && tiefe.at(fund) >= 0) { --fund; if(tiefe.at(fund) < tiefe.at(fund + 1)) ordner.push_back(pfade.at(fund)); };Aber auch dieses musst doch sicher nochmal ändern

-
vielleicht ist mir da eine sache noch nicht klar, fund enthält die Position von der gesuchten string. Und tiefe die Position von allen ordnern in dem vektor.
-
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