Übungsprojekt: Dateiinhalt auswerten
Das Programm zählt gelesene Textzeilen und durch Leerraum getrennte Wörter. Außerdem erstellt es eine Häufigkeitstabelle. Die Quelldatei wird nur gelesen. Übergib ihren Pfad beim Start, etwa ./statistik.exe beispiel.txt in PowerShell.
Übungsprojekt: Dateiinhalt auswerten#
Übungsprojekte · Lektion 57 von 60
Voraussetzungen: Dateien, Maps, main-Argumente. Lernziel: Du verarbeitest eine Eingabedatei, ohne ihren gesamten Inhalt gleichzeitig zu speichern.
Das Programm zählt gelesene Textzeilen und durch Leerraum getrennte Wörter. Außerdem erstellt es eine Häufigkeitstabelle. Die Quelldatei wird nur gelesen. Übergib ihren Pfad beim Start, etwa ./statistik.exe beispiel.txt in PowerShell.
Vollständiges Programm#
1#include <fstream>2#include <iostream>3#include <map>4#include <sstream>5#include <string>6 7int main(int argc, char* argv[]) {8 if (argc != 2) {9 std::cerr << "Aufruf: statistik <dateipfad>\n";10 return 1;11 }12 std::ifstream datei{argv[1]};13 if (!datei) {14 std::cerr << "Datei nicht lesbar\n";15 return 1;16 }17 constexpr unsigned long long maximum{1'000'000};18 unsigned long long zeilen{}, woerter{};19 std::map<std::string, unsigned long long> haeufigkeit;20 std::string zeile;21 while (std::getline(datei, zeile)) {22 if (zeilen == maximum) {23 std::cerr << "Zu viele Zeilen fuer dieses Uebungsprogramm\n";24 return 1;25 }26 ++zeilen;27 std::istringstream eingabe{zeile};28 std::string wort;29 while (eingabe >> wort) {30 if (woerter == maximum) {31 std::cerr << "Zu viele Woerter fuer dieses Uebungsprogramm\n";32 return 1;33 }34 ++woerter;35 ++haeufigkeit[wort];36 }37 }38 if (!datei.eof()) {39 std::cerr << "Fehler beim Lesen\n";40 return 1;41 }42 std::cout << "Zeilen: " << zeilen << "\nWoerter: " << woerter << '\n';43 for (const auto& [wort, anzahl] : haeufigkeit) {44 std::cout << wort << ": " << anzahl << '\n';45 }46}Die Definition eines Wortes#
Ein Token ist eine nach vereinbarten Regeln abgegrenzte Einheit. Hier ist jedes durch Leerraum getrennte Token ein Wort. Hallo und Hallo, sind daher verschieden, ebenso C++ und c++. Das ist eine bewusste einfache Definition, keine vollständige sprachwissenschaftliche Worterkennung.
Die Map sortiert Schlüssel nach ihrer Vergleichsregel. Das ist nicht automatisch die alphabetische Sortierung jeder menschlichen Sprache. Unicode-gerechtes Umwandeln von Groß- und Kleinbuchstaben wäre eine eigene Aufgabe; ein byteweises tolower reicht dafür nicht allgemein.
Speicher und Grenzen#
Das Programm liest zeilenweise. Trotzdem bleibt Speicher nötig: für die längste gelesene Zeile und für jedes unterschiedliche Wort in der Map. Die Zählgrenze verhindert endlos wachsende Anzahlen, setzt aber keine harte Bytegrenze für eine einzelne extrem lange Zeile. Für beliebige nicht vertrauenswürdige Großdateien wären zusätzliche Größen- und Speichergrenzen nötig.
Eine letzte Zeile ohne abschließenden Zeilenumbruch wird ebenfalls gezählt. Eine leere Datei ergibt null Zeilen und null Wörter. Ein Zeilenumbruch allein erzeugt eine leere gelesene Zeile.
Übung#
Prüfe eine Datei mit rot blau in der ersten und rot in der zweiten Zeile, auch ohne abschließenden Zeilenumbruch.
Lösung
Zwei Zeilen, drei Wörter, blau: 1 und rot: 2. Ergänze danach eine fehlende Datei und einen Programmaufruf ohne Argument: Beide müssen mit Fehlermeldung und Fehlerstatus enden.
Weiterlernen#
Zurück: Übungsprojekt: Notizen dauerhaft speichern · Kursübersicht · Weiter: C++-Glossar: Fachbegriffe verständlich erklärt
Kommentare 0
Kommentare sind für diese Seite deaktiviert.