xtp file durchsuchen
-
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; }
-
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.