Wörter Zählen

Hashimura

Grünschnabel
Das Programm soll Wörter zählen und läuft noch nicht so ganz.
CSS:
#include <fstream>
#include <iostream>
#include <string>
#include <cstdlib>
#include <iomanip>
 using namespace std;

 int main ( )
 {
 char c;                                                //Hilfsvariable
 int wort = 0;                                          //Variable der Wortzähler
 bool zustand;                                          //Wahrheitswert zustand

    ifstream ifs;                                       //variable
    ifs.open("eingabe.txt");                            //öffnet die datei

    if (!ifs)                                           //Wenn die Datei nicht geöffnet werden kann gebe Fehlermeldung aus
    {
        cerr << "\nERROR : Datei kann nicht geöffnet werden !" << "eingabe.txt" << endl;
        exit(1);
    }

    while(( c = ifs.get()) != EOF )                     //einleseschleife
    {
        if(isspace(c) ||ispunct(c))                     //Auf leerzeichen prüfen
        {
            zustand=0;                                  //Wenn ein leerzeichen vorhanden ist ist zustand = 0
        }
        else                                            //alles andere ist zustand = 1
        {
            zustand=1;
        }
        if (zustand==0)                 //schleife für erhöhung der zähler
        {
            wort+=1;
        }
    }
cout << "In diesen Text sind " << wort << " Woerter\n"; //ausgabe der Zähler
return 0;
}

Nur wie kann ich zählen, wie oft sich der zustand von 1 auf 0 wechselt??
 

cwriter

Erfahrenes Mitglied
Hi

Das Programm soll Wörter zählen und läuft noch nicht so ganz.
Im Prinzip ist dein Ansatz schon sehr gut. Die problematische Stelle ist wohl hier:
C++:
        if(isspace(c) || ispunct(c))                    //Auf leerzeichen prüfen
        {
            zustand=0;                                 //Wenn ein leerzeichen vorhanden ist ist zustand = 0
        }
        else                                            //alles andere ist zustand = 1
        {
            zustand=1;
        }
        if (zustand==0)                //schleife für erhöhung der zähler
        {
            wort+=1;
        }
Was du nun willst: Du willst ja nur von 1 (innerhalb eines Wortes) auf 0 (Leerzeichen) wechseln. Hast du ja auch schon gut erkannt:
Nur wie kann ich zählen, wie oft sich der zustand von 1 auf 0 wechselt??
Nun: Da ein Wechsel nur stattfinden kann, wenn der ursprüngliche Werte ungleich dem neuen Wert ist, kannst du überprüfen, ob ein Wechsel stattfinden würde. Somit wäre es dann
C++:
        if(isspace(c) || ispunct(c))                    //Auf leerzeichen prüfen
        {
            if(zustand) {                                    //Wenn ein Wort direkt davor stand, mache was. Ansonsten (wenn zuvor ein Leerzeichen war), kann der Status (zustand == 0) ja erhalten bleiben.
                zustand=0;                                 //Wenn ein leerzeichen vorhanden ist ist zustand = 0
                wort++;
            }
        }
        else                                            //alles andere ist zustand = 1
        {
            zustand=1;
        }
        //Das Schnipsel brauchst du dann auch nicht mehr

Gruss
cwriter

/EDIT: Kleiner Nachtrag:
C++:
if (zustand==0)                //schleife für erhöhung der zähler
Detail: Das ist keine Schleife, sondern eine Verzweigung. Nomenklatur halt.

Weiteres Detail: Du liest istream::get() in einen char. Das reicht normalerweise, aber eigentlich gibt istream::get() einen int zurück. Und der kann grösser sein als ein char (tatsächlich ist sehr oft ein int 4 Bytes und ein char 1 Byte gross). Siehe http://www.cplusplus.com/reference/istream/istream/get/

Ansonsten scheint dein Code korrekt zu sein - falls du eine weitere Herausforderung suchst, kannst du versuchen, mehr Bytes auf einmal in den Speicher zu lesen und dann die Bytes von dort aus zu lesen. Das ist nicht einfach eine dumpfe Übung, sondern es wird tatsächlich so gemacht: Denn einzelne Bytes aus einer Datei zu lesen ist zwar völlig korrekt, aber auch sehr langsam. Die genaue Erklärung, warum das so ist, ist ein bisschen kompliziert. Vereinfacht, als Metapher: Wenn du einen Sack Kies transportieren willst, bist du schneller, wenn du gleich den ganzen Sack nach Hause trägst, als wenn du Steinchen für Steinchen heimholst. Zwar läufst du ein bisschen langsamer, wenn du eine höhere Last aufs Mal hast, aber du musst nur einmal laufen. Bei Computern ist es sinngemäss ähnlich.
 
Zuletzt bearbeitet: