Dateistatistik (Uebung aus einem Buch) - Wo ist der Fehler?



  • Hallo,
    in dem Buch, dass ich zurzeit durcharbeite (von Ulrich Breymann, "C++ - Eonfuehrung und professionelle Programmierung") gibt es eine Aufgabe bei der es darum geht, die Statistik einer Datei zu ermitteln (Anzahl der Zeichen, der Worte und der Zeilen).
    Das hab ich dann auch gemacht - wie ich dann aber feststellen musste ist diese Aufgabe von Ulrich Breymann etwas anders geloest worden. Doch finde ich meinen Loesungsansatz eigtl. nicht schlecht.
    Ich habe nur ein Problem bei der Sache... Das 'neue Zeile'-Zeichen wird auch als Zeichen dazugezaehlt, trotz der Anweisung if(zeichen != '\n') anzahlzeichen++;
    Woran liegt denn das?

    Meine Testdatei hat folgenden Inhalt:

    aaa aaa
    aaa
    

    (inklusive einer "Leerzeile" zum Schluss)
    Das Ergebnis muesste dann wie folgt lauten:

    Anzahl der Zeichen: 10
    Anzahl der Worte: 3
    Anzahl der Zeilen: 3
    

    Stattdessen zeigt er mir aber bei 'Anzahl der Zeichen' 12 an. Daher nehme ich an, dass die 'neue Zeile'-Zeichen dazugezaaehlt werden - und WARUM das so ist verstehe ich nicht...
    Hier der Code (die kritische Zeile habe ich mit einem Kommentar versehen):

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    
    using namespace std;
    
    int main()
    {
    	string filename;
    	char zeichen, vorherzeichen;
    	vorherzeichen = ' ';
    	int anzahlzeichen = 0, anzahlworte = 0, anzahlzeilen = 1;
    	vector<char> inhalt;
    	ifstream fObj;
    
    	cout << "Bitte Name der Datei eingeben: ";
    	getline(cin, filename);
    
    	fObj.open(filename.c_str(), ios::binary | ios::in);
    
    	if(!fObj)
    	{
    		cout << "\n\nEs ist ein Fehler beim Lesen der Datei aufgetreten!";
    		cout << "\nBitte ENTER druecken, um das Programm zu beenden ...";
    		getline(cin, filename);
    		return -1;
    	}
    	else
    	{
    		while(fObj.get(zeichen))
    		{
    			inhalt.push_back(zeichen);
    
    			if(zeichen != '\n' && zeichen != ' ' && (vorherzeichen == '\n' || vorherzeichen == ' '))
    				anzahlworte++;
    
    			if(zeichen == '\n')
    				anzahlzeilen++;
    
    			if(zeichen != '\n')		// Zaehle eine neue Zeile NICHT als Zeichen
    									// funktioniert nicht
    				anzahlzeichen++;
    
    			vorherzeichen = zeichen;
    		}
    
    		cout << "\n\nAnzahl an Zeichen: " << anzahlzeichen << endl;
    		cout << "Anzahl an Worten: " << anzahlworte << endl;
    		cout << "Anzahl an Zeilen: " << anzahlzeilen << endl;
    
    		cout << "\nMoechten Sie den kompletten Dateiinhalt wiedergeben(j/n)? ";
    		cin.get(zeichen);
    
    		if(zeichen == 'j' || zeichen == 'J')
    		{
    			cout << endl << endl;
    			cout << "DATEIINHALT" << endl;
    			cout << "***********" << endl << endl;
    
    			for(int i=0; i<inhalt.size(); i++)
    				cout << inhalt[i];
    
    			cout << endl;
    		}
    
    		fObj.close();
    		fObj.clear();
    	}
    
    	string temp;
    	cout << "\n\nBitte ENTER druecken, um das Programm zu beenden ...";
    	getline(cin, temp);
    
    	return 0;
    }
    

    Kann mir jemand helfen?
    Suche schon die ganze Zeit verzweifelt nach dem Fehler 😞

    Gruss,
    Cartman



  • Vielleicht ist bei dir der Zeilenumbruch nicht nur "\n", sondern "\r\n".

    Lies doch die einzelnen Zeilen mit std::getline() in einen String und zähle dort weiter.



  • Hm, du hast Recht.

    Wobei ich das komisch finde.

    Im Buch steht 'Der Schalter ios::binary verhindert, dass Zeilenendkennung \n in CR/LF umgewandelt wird' - dies scheint aber offensichtlich nicht der Fall zu sein...

    Denn mit folgendem Code:

    if(zeichen != '\n' && zeichen!= '\r')
    

    funktioniert das Programm...

    danke fuer deine Hilfe - aber merkwuerdig find ich das schon... wozu soll das 'ios::binary' denn dann noch gut sein?

    Gruss,
    Cartman



  • Das bedeutet, dass du binär einliest und nicht als Text.


Anmelden zum Antworten