Vermeintliche einfache Aufgabe zu streams, aber sie hat es in sich, brauche Hilfe
-
Liebe Community,
Ich möchte mich mit einer vermeintlich einfachen Frage an euch wenden die mich aber schon seit Tagen beschäftigt und bei deren Bearbeitung ich einfach nicht weiterkommen.
Die Aufgabe liest sich mal sehr leicht:
Schreibe ein C++ Programm welches die Datei faust.txt öffnet und die Anzahl der Zeilen und die Anzahl der Wörter GLEICHZEITIG!! in der Konsole ausgibt.Und dieses gleichzeitig ist es was mich in den Wahnsinn treibt.
Die Lösung für hintereinander ausgeben also mit zweimaligem Ausführen des Programms war nicht schwierig.
Hier meine Lösung
#include <iostream> #include <fstream> #include <string> #include <stdlib.h> using namespace std; int main(int argc, const char * argv[]) { int wordcounter = 0; int linecounter = 0; ifstream file ("E:\\Programmieren\\faust.txt"); if (file.is_open()) { while (!file.eof()) { string b; string a; file >> a; getline(file, b); linecounter++; wordcounter++; } cout << linecounter <<endl; cout << wordcounter <<endl; } else { cout << "Die Datei konnte nicht geoeffnet werden." << endl; } }
Einmal wordcounter und file>>a auskommentiert füt die Zeilen, für die Wörter die anderen beiden.
Bringt beides ein richtiges Ergebnis.Nun können aber file >>a und getline(file, b); nicht gleichzeitig ausgelesen werden,
Ist mir klar, ich hab versucht es mit einem Char umzubauen für Leerzeichen bzw. Zeilenumbruchif (file.is_open()) { int linecounter = 0; int wordcounter = 0; char ch; while (!file.eof()) { // nächstes Zeichen einlesen ch = file.get(); // bei einem Zeilenumbruch die Anzahl der Wörter und der Zeilen erhöhen if (ch == '\n') { linecounter++; wordcounter++; } // bei einem Leerzeichen die Anzahl der Wörter erhöhen if (ch == ' ') { wordcounter++; } } cout << "Die Datei enthaelt " << linecounter << " Zeilen mit insgesamt " << wordcounter << " Woertern"<< endl;
So damit bekomme ich zwar die Anzahl der Zeilen korrekt raus aber nicht die Anzahl der Wörter.
Das Beispiel könnte man mit jeder beliebigen Textdatei lösen.
Kann mir jemand einen Tipp geben wo mein Denkfehler ist und wie eine gemeinsame Ausgabe beider Parameter bei einem Programmlauf funktionieren könnte.
Wie gesagt bin noch Anfänger und jetzt mit meinem Latein schon am Ende.
-
@montanistikus1 Wörter können auch dirch mehrere Whitespace hintereinander getrennt sein.
Eine Zeile aus lauter Leerzeichen hat keine Wörter.
Du darfst nur bei einem Wechsel (druckbares Zeichen nach Whitespace) zählen.
-
Hallo Dirk
Danke für deine Antwort
Ja es hapert an der if condition bei den Wörtern.
Wie gieße ich das was du sagst in eine if conditionIf ( char=' ' && ??
Da wirds schwierig
-
Das mehrere Leerzeichen ginge ja auch mit einer || Verknüpfung, was fehlt ist die condition wie Worte sicher erkannt werden
Mit meiner Methode fehlen mir bei der Datei ganze 11.500 Worte
-
Grundsätzlich machst Du schonmal falsch:
auf fehler (oder eof) prüfen
lesen
(eventuell mist) verarbeitenRichtig:
lesen
auf fehler (oder eof) prüfen
wenn kein fehler: verarbeiten
-
@montanistikus1 sagte in Vermeintliche einfache Aufgabe zu streams, aber sie hat es in sich, brauche Hilfe:
Mit meiner Methode fehlen mir bei der Datei ganze 11.500 Worte
Was gilt denn ein Wort?
Gehören Zahlen auch dazu?
Wie werden Wörter getrennt?Du wirst dir den Zustand (im Wort, außerhalb vom Wort) merken müssen.
-
Kannst du mir erklären weshalb?
Wieso nicht auf offene Datei prüfen vor dem Lesen?Mein Gedanke war: Wenn 2 char hintereinander nicht ' ' sind muss es ein Wort sein. Dumm aber bei einem englischen File wo das I für ich ja auch ein Wort ist.
Hab das mal probiert kam trotzdem Blödsinn raus hab es mit Word und Wörter zählen verglichen.
Bei Methode 1 geht ja alles nur gleichzeitig geht's nicht und weiss nicht wieso
-
um das da gehts:
@montanistikus1 sagte in Vermeintliche einfache Aufgabe zu streams, aber sie hat es in sich, brauche Hilfe:
while (!file.eof()) { // nächstes Zeichen einlesen ch = file.get();
file
geht eof nachdem Du versuchst mitfile.get()
zu lesen. Das bekommst Du aber vor der Verarbeitung bei Deinem Code nicht mit.
-
@montanistikus1 sagte in Vermeintliche einfache Aufgabe zu streams, aber sie hat es in sich, brauche Hilfe:
Wieso nicht auf offene Datei prüfen vor dem Lesen?
Das schon. Aber dann kannst Du gleich abbrechen:
if (!file.is_open()) { std::cerr << "Couldn't open file \"faust.txt\" for reading :(\n\n"; return EXIT_FAILURE; }
-
@montanistikus1 sagte in Vermeintliche einfache Aufgabe zu streams, aber sie hat es in sich, brauche Hilfe:
Mein Gedanke war: Wenn 2 char hintereinander nicht ' ' sind muss es ein Wort sein. Dumm aber bei einem englischen File wo das I für ich ja auch ein Wort ist.
Dann reicht auch ein Buchstabe.
aber was ist mit 123 oder a,b oder montanistikus1 oder r2d2 und verdammt nochmal!!1!11!
was gilt da als Wort (und wie ist das bei Word)?
-
Um auf die eigentliche Fragestellung zurückzukommen: Falls du stringstreams verwenden darfst kannst du mit getline die Zeile lesen, mit der Zeile einen stringstream initialisieren und mit >> die Worte in der Zeile lesen.
-
Danke mittag wie gesagt mache einen udemy Kurs stringstreams kenne ich noch nicht bin jetzt erst bei vectoren
Könntest du mir erklären wie das funktioniert?
Danke
-
@montanistikus1 Das funktioniert wie beim fstream, nur dass du den stream nicht mit einer Datei initialisiert sondern mit einem String.
also sowas:
#include <sstream> ... ... string linestr; string wordstr; istringstream strm(linestr); while (strm >> wordstr) wordcounter++;
linestr bekommst du natürlich von getline ..
-
#include <iostream> #include <sstream> #include <string> using namespace std; int wordsinline(string &zeile) { istringstream is{zeile}; string tmp; int count {0}; while(is >> tmp) ++count; return count; } int main() { string zeile {"wieviel Wörter sind in dieser Zeile drin"}; // Zeilen aus Deiner Datei lesen kannst Du ja // Mit jeder gefundenen Zeile dann eine passende Funktion aufrufen: int wcount = wordsinline(zeile); // in einer geeigneten Variablen aufaddieren ... // ... // am Ende ausgeben cout << wcount; }
-
Vielen Dank für eure Hilfe
Wie gesagt bin ja noch Anfänger habe eigentlich C++ technisch wahrscheinlich erst das "Welpenstadium" abgeschlossen
(hatte erst Operatoren, Schleifen, Funktionen,Arrays, Streams und jetzt Vektoren)Da kommt man noch nicht zu so eleganten Lösungen. Aber vielen Dank ich werd versuchen die Lösung von belli nachzuvollziehen und dann in ein Programm zu gießen.
Danke an alle die mir hier mit Tipps und Hilfe zur Seite gestanden sind.
-
Obwohl die Definition von "Wort" immer noch nicht klar ist:
#include <cstdlib> #include <cctype> #include <fstream> #include <iostream> int main() { auto input_filename{ "faust.txt" }; std::ifstream is{ input_filename }; if (!is.is_open()) { std::cerr << "Couldn't open \"" << input_filename << "\" for reading :(\n\n"; return EXIT_FAILURE; } unsigned long long num_words = 0; unsigned long long num_lines = 1; bool in_word = false; for (;;) { // forever int ch = is.get(); if (ch == EOF) { if (in_word) { in_word = false; ++num_words; } break; } if (std::isspace(ch)) { if (in_word) { in_word = false; ++num_words; } if (ch == '\n') ++num_lines; continue; } in_word = true; } std::cout << "Number of words: " << num_words << '\n' << "Number of lines: " << num_lines << "\n\n"; }
-
Vielen lieben Dank auch dir Swordfish
Für mich persönlich war die Definition als ich an die Aufgabe ranging: Ein Wort ist ein String welches vom vorhergehenden durch ein ' ' getrennt ist und auch vom nachfolgenden mit einem ' ' getrennt ist.
Warum das mit file >> a so gut funktioniert und die Zahl der Wörter mit der MS Word Zählung übereinstimmt und bei mir Mist rauskam ist mir noch nicht klar.