Wortzähl - Funktion



  • Hallo liebe Community,

    also ich bin ein bisschen beim Üben und hab mir gedacht, schreib einmal ein Programm das eine Textdatei bekommt und diese analysiert.

    aber eine Funktion funktioniert irgendwie nicht richtig und ich finde meinen Fehler nicht, hoffe ihr könnt mir helfen.

    Also hier mein schöner Code:

    int woerterzaehlen()
    {
      int i = 0;
      int wortzahl = 0;
      string buffer;
      string text;
      string datei;
      ifstream file;
    
      cout << "Welche Datei soll eingelesen werden? ";
      cin >> datei;
    
      cout << endl;
    
      file.open(datei.c_str());
    
      if(file)
      {
        while(!file.eof())
        {
          getline(file, buffer);
          text += buffer + "\n";
        }
    
        file.close()
      }
      else
      {
        cout << "Datei nicht vorhanden" << endl;
      }
    
      for(i = 1; i <= text.length(); i++)
      {
        if((text[i] == ' ') && (text[i - 1] != ' '))
        {
          wortzahl++;
        }
      }
      wortzahl++;
    
      cout << "Die Datei enthält: " << wortzahl << " Wörter!" << endl;
    
      return 0;
    }
    

    so und als testdatei, hab ich irgendwas zusammengeschrieben: die datei enthält 1216 wörter laut word aber mein programm gibt nur 1016 wörter an!



  • Heinzi1991 schrieb:

    so und als testdatei, hab ich irgendwas zusammengeschrieben: die datei enthält 1216 wörter laut word aber mein programm gibt nur 1016 wörter an!

    Hast du Satzzeichen in der Datei?



  • ja satzzeichen sind vorhanden, like !, ?, : und so weiter!
    kann dies stören?



  • Deine Testmenge ist zu groß. Erstelle eine Datei mit einem Satz und zähle händisch - dann siehst du auch schnell wo die Fehler sind, alls dir alle gefunden Worte ausgeben und vergleiche mit dem was du händisch gezählt hast.

    Einfach überschaubare Datenmengen verwenden, dann ist die Sachen viel viel viel einfacher.



  • Was ist denn am Ende von Zeilen?

    Du liest die Datei zeilenweise ein und konkatenierst sie mit einem Zeilenumbruch (so weit so gut). Beim Zählen beachtest du aber nur Leerzeichen.

    Guck mal hier.
    Damit kannst du sowas machen:

    for(std::size_t i = 1; i < text.size(); ++i)
        if ( std::isspace(text[i]) && !std::isspace(text[i-1])
             wortzahl++;
    


  • danke an Skym0sh0 mit deiner funktion hat es perfekt geklappt; die verschwundenen 200 wörter sind aufgetaucht! danke!



  • Du musst letztendlich definieren was als Teil eines Wortes zählt, Buchstaben und Zeichen wie "êöäüîß" usw. musst du auch beachten. Alle anderen Zeichen z.b. "$/()[}]}{=,.:;-_" usw. sind Trennzeichen. Da es mehr Trennzeichen gibt würde ich nur die Zeichen die zu einem Wort gehören prüfen und nicht andersrum. Gehen tut aber beides.

    danke an Skym0sh0 mit deiner funktion hat es perfekt geklappt; die verschwundenen 200 wörter sind aufgetaucht! danke!

    Höchst unwahrscheinlich, es sei denn du hast keinen Text mit Satzzeichen... 🙄



  • DarkShadow44 schrieb:

    Höchst unwahrscheinlich, es sei denn du hast keinen Text mit Satzzeichen...

    doch, das geht. Das Leerzeichen kommt nämlich *nach* dem Satzzeichen... solange er die Wörter nur zählen und nicht weiter auswerten will, funktioniert das.



  • DarkShadow44 schrieb:

    Höchst unwahrscheinlich, es sei denn du hast keinen Text mit Satzzeichen... 🙄

    Wo liegt das Problem? Solange die Satzzeichen nicht durch ein Leerzeichen auf beiden Seiten von der Wörtern abgeschnitten werden, ist es dem Algorithmus egal.



  • Die ursprüngliche Version hätte funktioniert, wenn Du statt '\n' ein ' ' als Zeilentrenner eingefügt hättest.
    So aber hast Du '\n' als Zeilentrenner - und damit auch als Worttrenner zwischen dem letzten Wort einer Zeile und dem ersten der Folgezeile - gesucht hast Du aber nur nach ' ' als Worttrenner - deshalb findest Du pro Zeile ein Wort weniger.
    Die isspace - Funktion, die Skym0sh0 vorschlägt, erkennt dagegen mehrere verschiedene Zeichen als Trennzeichen und funktioniert deshalb in beiden Fällen.



  • Klar bei simplen Texten mit perfekter Struktur geht das. Aber wenn man alle Texte abdecken will nicht mehr:
    -Text mit ein/zwei/drei Optionen
    -Oder wenn der Text(kommt durchaus vor)schlecht formatiert ist
    -Doppel-Namen
    -Programmiersprachen: "testFunc(Test::k)"

    Klar es sind eher seltene Fälle, kommt halt drauf an wie perfekt mans lösen will.


Log in to reply