Textdatei auslesen
-
Hi,
Ich möchte in einer Textdatei(>100MB) nach bestimmten Schlüsselwörtern und Absätzen suchen. Jetzt bin ich noch nich allzu sehr mit c++(g++) und linux(Suse) vertraut und frag zum einen einfach mal hier wir ihr das problem angehen würdet, ob es z.B. sowas wie RegEx gibt was man benutzen könnte oder ähnliches.
Ich hab mir folgenden Lösungsansatz überlegt: Ich lese die Datei Byteweise aus und vergleiche den ausgelesenen char mit dem ersten char meines gesuchten Strings, falls gleich, vergleiche ich den Rest auf Übereinstimmung. Die übereinstimmenden Strings wollte ich in einer Map speichern mit dem Index(in der Textdatei) als Key und zurückgeben.Den Ansatz hab ich jetzt, teils als Pseudocode, teils als c++ code implementiert, er lässt sich kompilieren, beim ausführen steigt er jedoch mit einem Segementation Fault beim Aufruf der Funktion int findall(const char*, const char*) aus. Habe probiert das ganze mit SystemCalls oder mit Streams zu implementieren, es kommt jedoch immer der gleiche Fehler. Hab ich vielleicht in der Compilereinrichtung irgendwas verkehrt gemacht oder der gleichen? Benutze Suse 10.0 und g++.
//map<int, string>* mymap, int findall(const char* Sourcepath, const char* Search){ //std::ifstream Source(Sourcepath); char sign; std::string partid; int foundcount, file_dc, readed_chars, i=0; //Source datei öffnen if((file_dc = open(Sourcepath, O_RDONLY))==-1){ perror("open(Sourcepath)"); return -1; } else{ //byteweises einlesen do{ if((readed_chars = read(file_dc, &sign, 1)) == -1){ perror("read(file_dc)"); return -1; } else{ if(strcmp((const char*)sign, (const char*)Search[0])){ foundcount++; partid.append(&sign); } else{ partid.clear(); foundcount=0; i=0; } if(foundcount==sizeof(Search)&&sign=='\n') //mymap->insert(make_pair(Source.tellg(), partid)); std::cout<<"Part ID "<<partid<<std::endl; } i++; }while(readed_chars!=0); close(file_dc); } return 0; /*if(!(Source)) myexception("kann Datei nicht öffnen", ""); else{ //byteweises einlesen while(Source.get(sign)){ #ifdef DEBUG cout<<sign; #endif if(strcmp((const char*)sign, (const char*)Search[0])){ foundcount++; partid.append(&sign); } else{ partid.clear(); foundcount=0; i=0; } if(foundcount==sizeof(Search)&&sign=='\n') //mymap->insert(make_pair(Source.tellg(), partid)); i++; } }*/ }
Für Tipps oder Verbesserungen für die Zukunft(Stil, usw.) wäre ich ebenfalls dankbar, wie zuvor gesagt bin neu, hab vorher nur windows programmiert und hab von der ganzen Thematik noch nich wirklich nen gescheiten Plan.
Danke für die Hilfe
Daniel
-
Mach mal in Zeile 25 ein & vor das sign.
-
ne ich glaub das isses nich, hat glaub ich was mit dem konstruktor vom string zu tun. wenn ich den hinzu füge erhalte ich aber nen kompilerfehler
std::string partid = new string();
hier kennt er das new nicht.
std::string partid();
und hier kennt er die klassenmember append und clear nich.
-
Para_Dox schrieb:
std::string partid = new string();
hier kennt er das new nicht.
Bei new bekommst du einen Zeiger.
std::string partid();
und hier kennt er die klassenmember append und clear nich.
Das ist eine Funktionsdeklaration. Lass die Klammern weg.
-
MFK schrieb:
Das ist eine Funktionsdeklaration. Lass die Klammern weg.
und wie ist dann das beispiel hier zu verstehen?
http://www.cppreference.com/cppstring/string_constructors.htmldas sind doch keine funktionen oder? doch vielmehr implizite deklaration oder verwechsel ich was?
-
In dem Bespiel steht nirgendwo string foo().
Die casts bei strcmp verhindern, dass der Compiler die Typen prüft. Überhaupt kannst du strcmp nicht mit einem einzelnen char (und auch nicht mit dessen Adresse) benutzen. Und informier dich nochmal genau, was sizeof tut, vor allem mit Zeigern.
-
hast recht, ich kuck da nochmal nach, hatte gar nich damit gerechnet, dass er so weit kommt sollte ja mehr oder weniger pseudocode sein.
danke
PS: gibts noch andere möglichkeiten ne textdatei zu durchsuchen?
-
boost.regex
grep
...?