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.html

    das 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
    ...?


Anmelden zum Antworten