Anfängerprogramm - Feedback gesucht!
-
Hallo liebe Community,
ich habe zur Übung bzw. aus Spaß ein kleines Progrämmchen geschrieben, welches nach Angabe einer .txt Datei
-Nach einem selbst gewähltem Wort sucht und dessen Häufigkeit überprüft
-Die Gesamtzahl der Wörter ausgibt
-Die einzelnen Wörter und deren Häufigkeit ausgibt
-Das häufigste Wort ausgibtIch habe dieses "Thema" gewählt, weil ich denke es ist beinahe "grenzenlos" erweiterbar und etwas Besseres fällt mir nicht ein (Vorschläge hierbei auch gern gesehen, auch für andere unkreative Neulinge!)
Ich würde mich unheimlich über Verbesserungsvorschläge und Tipps bzw. Kritik freuen.
z.B.: "An jener Stelle ist es allgemein besser dies zu verwenden" oder vielleicht könnte ich den Code noch leserlicher gestalten (ja, habe PEP8 mal durchgelesen) etc. Manchmal macht man es sich ja komplizierter als es ist...Ich habe auch ein kleines Problem bzw. eine Frage:
In einem Satz kommen ja auch Punkte vor (sollten sie zumindest). Mein Programm kommt halbwegs (ob es auch "gut" gemacht ist erfahre ich hoffentlich bald) damit klar. Wenn aber die Wörter ausgegeben werden, nimmt "er" manchmal bei Wörtern am Satzende den Punkt mit und das Wort heißt zum Beispeil "Beispiel.".
Ist an sich ja verständlich, "er" ließt bis zum Leerzeichen, denke ich mal.Hat jemand eine Idee wie ich das wegbekomme? Konnte den -Operator irgendwie nicht an geeigneter Stelle anwenden

Also habe mir gedacht
try Punkt abziehen -> String -"." catch normalen string verwendenging aber nicht wirklich...

#include<iostream> #include<vector> #include<string> #include<fstream> using namespace std; // Wort mit zugehöriger Anzahl struct word_with_amount { int word_amount; string word_type; word_with_amount(int a, string w) :word_amount(a), word_type(w){} }; int main() { cout << "- FILE SCANNER -\n" << "Note: This Program searches with case sensitivity.\n\n" << "Enter the path and name of a textfile: \n"; // Datei öffnen string filename; cin >> filename; ifstream ist(filename.c_str()); if (!ist) { //überprüfen cout << "Error. Couldn't open file.\n"; return 1; } //Alle Wörter der (Text)-Datei in einen Vector packen vector<string> words; string word = ""; while(ist>>word) words.push_back(word); //Nach einem bestimmten Wort suchen und die Häufigkeit ausgeben cout << "Enter word to scan for: "; string target_word; cin >> target_word; int amount = 0; int word_count = 0; for(int i=0; i<words.size(); i++) { word_count += 1; //gesamtanzahl der Wörter mitzählen //Häufigkeit des eingegeben Wortes Zählen if ( words[i] == target_word || words[i] == (target_word+".") || words[i] == (target_word+",") || words[i] == (target_word+";")) { amount += 1; } } //Ausgabe if (amount == 1) { cout << "The word \"" << target_word << "\" appears once in the file.\n"; } else { cout << "The word \"" << target_word << "\" appears " << amount << " times in the file.\n"; } if (word_count == 1) { cout << "The file has a total of 1 word.\n\n"; } else { cout << "The file has a total of " << word_count << " words.\n\n"; } //Vector für Wörter mit zugehöriger Häufigkeit vector<word_with_amount> wordcounts; int word_amount = 0; string word_type = ""; //Überprüfen, welche Wörter und wie oft diese in der .txt Datei vorkommen for(int i=0; i<words.size(); i++) //"Läuft" von Wort zu Wort { word_type = words[i]; for(int x=0; x<words.size(); x++) //schaut für jedes Wort, { //wie oft dieses vorkommt if( (words[i] == words[x]) || (words[i]+"." == words[x]) || (words[i]+"," == words[x]) || (words[i]+";" == words[x])) { word_amount += 1; } } //überprüfen ob ein Wort schoneinmal in den Vector aufgenommen wurde int exist = 1; for(int i=0; i<wordcounts.size(); i++) { if ( word_type == wordcounts[i].word_type || word_type == wordcounts[i].word_type+"." || word_type == wordcounts[i].word_type+"," || word_type == wordcounts[i].word_type+";") { exist = 0; } } if (exist == 1) { wordcounts.push_back(word_with_amount(word_amount, word_type)); word_amount = 0; } else {word_amount = 0;} } //Ausgabe for(int i=0; i<wordcounts.size(); i++) { cout << "\"" << wordcounts[i].word_type << "\", " << wordcounts[i].word_amount << " time(s)\n"; } //Das häufigste Wort in der Datei ermitteln+ausgeben int highest_count = 0; string frequent_word = ""; for(int i=0; i<wordcounts.size(); i++) { if(wordcounts[i].word_amount>highest_count) { highest_count = wordcounts[i].word_amount; frequent_word = wordcounts[i].word_type; } } cout << "\nThe most common word is \"" << frequent_word << "\". It appears " << highest_count << " times.\n"; //Verhindern dass sich die Konsole gleich schließt cin.clear(); cout << "Please enter a character to exit\n"; char ch; cin >> ch; return 0; }Vielleicht schaut's sich ja mal jemand durch

Mit freundlichen Grüßen,
HarteWare
P.S.: Falls man nur bei Problemen posten sollte und nicht zwecks Kritik, werde ich das bestimmt merken und mir für die Zukunft merken. Das ist auch der einzige Grund, weshalb ich das ganze Ding reingekleistert hab. Aber so gesehen, ich komme auch an einem bestimmen Punkt nicht weiter
und man will ja irgendwo sich keine falschen Techniken angewöhnen...
-
Schau dir mal die beiden Beiträge von "Werner Salomon" unter http://www.c-plusplus.net/forum/p2325671#2325671 an (auch wenn das evtl. zurzeit deine Programmierfähigkeiten übersteigt

-
...
-
Vorerstmal vielen Dank für die Antworten!
Ich werd mir den Code von Salomon mal anschauen, kapier jetzt auf den ersten Blick nicht alles, aber vielleicht finde ich da was!
Das mit dem else-block hat mich auch schon gestört, aber die mehr oder weniger einfache Lösung ist mir nicht eingefallen, danke! Es stimmt tatsächlich, !, ?, "" und () habe ich bis jetzt noch nicht in Betracht gezogen, das gehört natürlich auch dazu!
Das mit dem "generischen" habe ich jetzt nicht ganz verstanden, also da lässt sich etwas machen, dass diese gefühlt 20 if-Abfragen vereinfacht?
Das mit dem a la Kommandozeile hab ich mir auch schon im Hinterkopf gedacht, ich werds mal versuchen!
nochmals Danke für die Tipps

mfg
HarteWare
-
...
-
Swordfish schrieb:
Da gäb's zum Beispiel std::ispunct().
Wow, das sieht schonmal ziemlich viel versprechend aus, vielen Dank!
Mich würde interessieren nach was du da gesucht hast, damit ich in Zukunft das vielleicht auch selber kann!
Da merke ich grad, auch ohne die schon fertige funktion hätte ich dafür auch selbst eine schreiben sollen/(können)...mfg

HarteWare
-
...
-
Hallo,
vielen Dank für den Hinweis, ich werde in Zukunft die Linkliste in meine Suchen miteinbeziehen.
Ich habe noch folgendes Problem:
Dieses std::ispunct(); scheint mir für C "konzipiert" zu sein. Jedenfalls meckert der Compiler bei der beschriebenen Zuweisung in dem link (einfach mal zwei posts drüber schauen). Bei Zuweisung auf ein string element eines Vector bekomme ich:
error: cannot convert 'std::string {aka std::basic_string<char>}' to 'char' in assignment
Bei direkter zuweisung eines strings a la "Peace, heyho!" bekomme ich:
*error: invalid conversion from 'const char' to 'char' [-fpermissive]
**
ich kann diese Fehlermeldungen leider nicht "entschlüsseln". Dem scheint halt irgendwas mit den Typen nicht zu passen, aber eine Lösung sehe ich dafür nicht.Hier der Ort an dem es geschieht (falls ich wirklich ein kompilierbares Beispiel zusammenstellen muss, kann ich das noch zusammenbasteln)
Das str[999] ist weil bei str[] kommt die Meldung:error: storage size of 'str' isn't known;
(also hab ichs mal festgelegt auf
eine Größe, welche wohl kein Wort übertreffen wird.int y = 0; char str[999]; for(int i=0; i<wordcounts.size(); i++) { str[999] = wordcounts[i].word_type; //analog für eine // Zuweisung mit "String" while(str[y]) { if (ispunct(str[y])) //...EDIT: schätze mal die code tags gehen nicht, weil mein code beispiel "schlecht" ist? aka unvollständig
-
Du darfst in den code tags kein [b] oder so verwenden.
Was sollte std::ispunct("asd!"); denn deiner Meinung nach ausgeben?
-
KN4CK3R schrieb:
Du darfst in den code tags kein [b] oder so verwenden.
Was sollte std::ispunct("asd!"); denn deiner Meinung nach ausgeben?
Hi,
es sollte den boolean true ausgeben, wenn ich das aus dem von der Dokumentation gegebenen Codebeispiel richtig verstanden habe.
aah jetzt funktionierts mit den Tags, danke

mfg
HarteWare
-
Ich rede von dem Parameter, den du übergibst. Was würdest du erwarten, soll die Funktion mit deinem String machen?
-
Sie überprüft solange Zeichenketten im String sind, ob diese ein "punctuation character" enthalten, sprich: "geschrieben." oder "Hey!" oder "so," oder "(Bananen)" oder '"gedownloaded"'. Also ob es nicht nur "eine" Wörter sind, sondern diese noch Satzzeichen "angebunden" haben.
Was ich damit erreichen will ist schlicht und ergreifend, dass wenn ich das Wort "Apfel" in einem .txt Dokument habe und an anderer Stelle kommt es vor einem Komma vor, also "Apfel,", soll das Programm dies erkennen.
Gebe ich also nun alle Wörter der Datei, zusammen mit ihrer Häufigkeit aus, bekomme ich nicht
"Apfel", 1 mal
"Apfel,", 1 malsondern
"Apfel", 2mal
Denn es handelt sich ja eigentlich um das gleiche Wort...mfg
HarteWare
-
...
-
was du damit erreichen willst, ist mir schon klar. ich frage so umständlich damit du vllt selbst auf die lösung kommst. wenn die funktion das machen würde, was du dir vorstellst, dann würde sie für jeden satz true ausgeben. das ist dann eine information, die dich nicht sonderlich weiterbringt oder?
-
Hallo,
Erstmal vielen Dank für die Antworten!

ja, das mit dem umständlichen Fragen und selbst auf die Lösung kommen a la Sokrates hab ich auch schon etwas bemerkt
Also das es mir nur sagt, ob ein char ein "punctuation character" ist hab ich jetzt geschnallt. Ich werd einfach nochmal ein bisschen probieren wie es gehen könnte, ich sehe jetzt auch dass mein momentaner Ansatz nicht ganz funktioniert kann.

Leider besteht noch folgendes Problem:
Ich kann meinem char str[999] keinen "String" zuweisen, obwohl das in dem Codebeispiel gemacht wird! Ich zitiere:char str[]="Hello, welcome!";Das Problem dahinter habe ich noch nicht ganz erkannt...
mfg
HarteWare
EDIT: Das Problem hat sich nun mit der Zeit von selbst geklärt und ich habe eine funktionierende Methode gefunden.