Riesiger string (Bibel) aus Datei in andere Datei kopieren



  • ok danke, wenn ich die Datei 1:1 kopieren will versuch ich's mal wie du es beschrieben hast. Jetzt möchte ich ein Programm schreiben, bei dem man die gesamte Bibel nach beliebigen Wörtern durchsuchen kann um das mit den Strings zu üben. Das Problem ist jedoch, dass extrem viele Wörter nicht mitgezählt werden (habe teilweise selbst nachgezählt). Woran kann das liegen?

    Hier mein code:

    #include <iostream>
    #include <string>
    #include <fstream>
    #include <list>
    
    using namespace std;
    
    int main ()
    {
    
    	int WortZähler = 0;
    	list<string> Suchwörter;
    	list<string>::iterator Iter;
    
    	fstream file;
    
    	file.open("elb_bibel.txt");
    	if( !file ) {
    		cout << "error" << endl;
    	}
    
    	string Bibeltext;
    	string Zeile;
    
    	while( !file.eof() ) {
    	getline(file, Zeile);
    
    	//Bibeltext += " ";
    	Bibeltext += Zeile;
    	}
    
    	cout << "length: " << Bibeltext.length() << endl;
    	cout << "size: " << Bibeltext.size() << endl;
    	cout << "capacity: " << Bibeltext.size() << endl;
    
    	string such[] = {"Gott", "Nacht", "Tag", "Schoepfung", "Mose", "Wasser", "Licht"};
    
    	for( int i = 0; i <= 6; i++ ){
    		Suchwörter.push_back(such[i]);
    	}
    
    	for( Iter = Suchwörter.begin(); Iter != Suchwörter.end(); Iter++ ){
    		cout << *Iter << endl;
    	}
    
            unsigned long pos = 0;
    	for( Iter = Suchwörter.begin(); Iter != Suchwörter.end(); Iter++ ){
    
    		while( pos != string::npos ) {
    		pos = Bibeltext.find(*Iter, pos);
    
    		if( string::npos==pos) {
    			cout << "nicht gefunden!" << endl;
    		} else {
    			++pos; // verhindert Endlosschleife
    			++WortZähler;
    		} 
    
    	}
    
    	cout << "\nDas Wort " << *Iter << " kommt " << WortZähler << " mal in der Bibel vor.\n\n";
    
    	WortZähler = 0;
    	pos = 0;
    
    	}
    
    	system("pause");
      return 0;
    }
    


  • Kay schrieb:

    Was für eine alternative gäbe es?

    Hallo Kay,

    die Alternative wäre, das Original direkt in die Kopie zu schreiben. Und zwar so:

    #include <iostream>
    #include <fstream>
    
    using namespace std;
    
    int main ()
    {
        ifstream Original("elb_bibel.txt");
        if( !Original.is_open() ) {
            cout << "error Original.txt" << endl;
        }
        ofstream Kopie("Kopie.txt");
        if( !Kopie.is_open() ) {
            cout << "error Kopie.txt" << endl;
        }
        Kopie << Original.rdbuf(); // Original nach Kopie kopieren
    
        cin.get(); // warte auf Tastatur
        return 0;
    }
    

    Gruß
    Werner



  • Hallo Werner,

    habe deine Methode, als auch die von Nexus (s. unten) benutzt, allerdings, werden nicht alle 3 Millionen Zeichen in die Datei kopiert, sondern nur an die 720.000. Ich denke einfach mal bei so einer riesigen Menge an Zeichen geht das nicht mehr so leicht?

    char c;
    	while( !Original.eof() ) {
    
    	c = Original.get();
    
    	if ( Original.good() ) 
    		Kopie.put(c);
    


  • Kay schrieb:

    Hallo Werner,

    habe deine Methode, als auch die von Nexus (s. unten) benutzt, allerdings, werden nicht alle 3 Millionen Zeichen in die Datei kopiert, sondern nur an die 720.000. Ich denke einfach mal bei so einer riesigen Menge an Zeichen geht das nicht mehr so leicht?

    Doch. Schau mal ob du wirklich die richtige Datei öffnest.

    Übrigens

    Werner Salomon schrieb:

    Kay schrieb:

    Was für eine alternative gäbe es?

    Hallo Kay,

    die Alternative wäre, das Original direkt in die Kopie zu schreiben. Und zwar so:

    #include <iostream>
    #include <fstream>
    
    using namespace std;
    
    int main ()
    {
        ifstream Original("elb_bibel.txt");
        if( !Original.is_open() ) {
            cout << "error Original.txt" << endl;
        }
        ofstream Kopie("Kopie.txt");
        if( !Kopie.is_open() ) {
            cout << "error Kopie.txt" << endl;
        }
        Kopie << Original.rdbuf(); // Original nach Kopie kopieren
    
        cin.get(); // warte auf Tastatur
        return 0;
    }
    

    Gruß
    Werner

    Warum wird bei Kopie << Original.rdbuf(); das failbit für Kopie gesetzt, wenn Original 0 Bytes hat? Das ist doch dämlich. 👎



  • Kay schrieb:

    Jetzt möchte ich ein Programm schreiben, bei dem man die gesamte Bibel nach beliebigen Wörtern durchsuchen kann um das mit den Strings zu üben. Das Problem ist jedoch, dass extrem viele Wörter nicht mitgezählt werden (habe teilweise selbst nachgezählt). Woran kann das liegen?

    Dein Code sollte im Prinzip funktionieren. Die Frage ist, ob z.B. 'Schoepfung' in der Textdatei nicht 'Schöpfung' geschrieben wird. Wird eines der Worte gar nicht gezählt? Kontrolliere doch mal, ob der Anfang und das Ende von 'Bibeltext' mit Anfang und Ende Deiner Datei übereinstimmen.

    ich sehe gerade Dein Posting:

    Kay schrieb:

    ..., allerdings, werden nicht alle 3 Millionen Zeichen in die Datei kopiert, sondern nur an die 720.000. Ich denke einfach mal bei so einer riesigen Menge an Zeichen geht das nicht mehr so leicht?

    3Millionen sind 3MB; das sollte bei den heutigen Rechnern kein Problem darstellen. Wenn Du Nexus' oder meinen Vorschlag benutzt hast schon gar nicht, da sich die Zeichen nie alle gemeinsam im Speicher befinden. Schau doch mal nach, wie der letzte Text lautet, der in die Kopie gechrieben wurde, und dann schaue bitte mit einem Texteditor in das Original, was danach kommt. Ich vermute, dass dort ein 'nicht-Text-Zeichen' folgt. Dann bricht der Lesevorgang ab.

    Du kannst es trotzdem kopieren, wenn Du die Dateien im Binär-Mode öffnest - mit 'ifstream Original( "elb_bibel.txt", ios_base::binary );'

    Gruß
    Werner



  • suseq schrieb:

    Warum wird bei Kopie << Original.rdbuf(); das failbit für Kopie gesetzt, wenn Original 0 Bytes hat? Das ist doch dämlich. 👎

    Nein das ist nicht dämlich, sondern es verhält sich so wie spezifiziert.

    Der Grund dafür ist einfach der, dass man mit

    if( Kopie << Original.rdbuf() )
        {
            // alles klar, Original wurde nach Kopie geschrieben
    

    einfach abfragen kann, ob da wirklich was kopiert worden ist.



  • Werner Salomon schrieb:

    suseq schrieb:

    Warum wird bei Kopie << Original.rdbuf(); das failbit für Kopie gesetzt, wenn Original 0 Bytes hat? Das ist doch dämlich. 👎

    Nein das ist nicht dämlich, sondern es verhält sich so wie spezifiziert.

    Der Grund dafür ist einfach der, dass man mit

    if( Kopie << Original.rdbuf() )
        {
            // alles klar, Original wurde nach Kopie geschrieben
    

    einfach abfragen kann, ob da wirklich was kopiert worden ist.

    Aber warum soll das ein Fehler sein, wenn es garnichts zum Kopieren gibt? Da muss man für leere Dateien immer eine Sonderbehandlung machen, wenn man ein Verzeichnis kopieren will.



  • suseq schrieb:

    Aber warum soll das ein Fehler sein, wenn es garnichts zum Kopieren gibt? Da muss man für leere Dateien immer eine Sonderbehandlung machen, wenn man ein Verzeichnis kopieren will.

    muss man nicht. Wenn leere Dateien ok sind, ignoriere einfach das failbit; nach dem Kopieren musst Du mit dem ostream 'Original' ja eh' nicht mehr arbeiten.



  • Super, hat geklappt, danke dir Werner. 🙂

    Da war so ein kleiner Pfeil im Text (Sonderzeichen nehme ich an), aber bitweise ging es dann.



  • Kay schrieb:

    char c;
    	while( !Original.eof() ) {
    	
    	c = Original.get();
    	
    	if ( Original.good() ) 
    		Kopie.put(c);
    

    charweise ne datei zu kopieren ist schon unter c ne schlechte weil langsame idee...
    das hat sich sicher mit c++ nicht geändert...

    lg lolo


Anmelden zum Antworten