Problem bei einer Aufgabe
-
Hi Leute!
Ich hab eine Aufgabe für die SChule zu machen und hänge da grad ein wenig...
Unser Thema ist Arrays. Und es geht um folgendes:
Es soll ein Satz eingelesen und dieser auf Kleinbuchstaben untersucht werden. alle kleingeschriebenen Vokale sollen separat in einem Array gezählt werden und die Konsonanten später aus der Differenz zwischen gesamtkleinenkonsonsnanten-vokalanzahl errechnet werden.mein ansatz war folgender:
#include <iostream> #include <conio.h> using namespace std; int main() { char satz[100]; int vokale[5]; int kChr; int anzKons; cout << "Bitte geben Sie einen Satz ein:" << endl; cin >> satz; for (int i=0; i < sizeof(satz)/sizeof(satz[0]); i++) { if (satz[i] >= 97 && satz[i] <= 122) { anzKons++; switch (satz[i]) { case 97: { vokale[0]++; break; } case 101: { vokale[1]++; break; } case 105: { vokale[2]++; break; } case 111: { vokale[3]++; break; } case 117: { vokale[4]++; break; } } } } cout << "Anzahl der Konsonanten: " << anzKons << endl; cout << "Darin enthalten sind: " << vokale[0]+vokale[1]+vokale[2]+vokale[3]+vokale[4]; getch(); return 0; }aber irgendwie kanns nicht gehen, weil ich im char keine zahlenwerte untersuchen kann, oder leigt mein fehler woanders? komm grad echt nicht weiter....
dankeschonmal!
liebe grüße
-
ViperNeo schrieb:
Es soll ein Satz eingelesen
Dann solltest du statt cin >> satz; eher cin.getline(satz, 99); verwenden. (Oder wenigstens
cin >> setw(100) >> satz; // maximal 99 Zeichen von stdin einlesenum segemtation-faults zu vermeiden.)
Dein Fehler liegt darin, dass du die Variablen nicht initialisierst. Merke: Lokale Variablen, erhalten per Default einen undefinierten Ausgangswert. => Mache aus
int vokale[5] = { 0, 0, 0, 0, 0 }; int anzKons = 0;Außerdem solltest du in der for-Schleife nicht sizeof(satz) / sizeof(char) verwenden, da deine Schleife sonst 100 mal durchlaufen wird. Nimm besser i < strlen(satz) als Abbruchbedingung.
Gruß Caipi
-
Caipi schrieb:
Dann solltest du statt cin >> satz; eher cin.getline(satz, 99); verwenden.
Hallo Caipi,
noch besser wäre die Verwendung eines Strings nebst der Funktion getline. Dann muss man sich nicht auf die (max.) Länge der Zeile festlegen.
std::string zeile; getline( std::cin, zeile );Caipi schrieb:
Außerdem solltest du in der for-Schleife nicht sizeof(satz) / sizeof(char) verwenden, da deine Schleife sonst 100 mal durchlaufen wird. Nimm besser i < strlen(satz) als Abbruchbedingung.
Die Werte von 'sizeof(satz) / sizeof(char)' sind zur Compile-Zeit bekannt. Jeder durchschnittliche Compiler sollte aus diesem Ausdruck eine Konstante machen können. Mit strlen() wird dagegen zur Laufzeit jedesmal eine Funktion aufgerufen; diese Variante ist mit hoher Wahrscheinlichkeit langsamer.
Gruß
Werner
-
Caipi schrieb:
int vokale[5] = { 0, 0, 0, 0, 0 };wozu die tipparbeit, wenn doch
int vokale[5] = {};reicht?
(nur um das mit setw zu erklären, ich denke caipi hat es wohl richtig gemeint:
operator>> versucht, alle chars in das array zu stopfen, bis ein whitespace kommt. setw sagt nur die maximale anzahl, die operator>> dort hinein stopfen soll. wenn du whitespaces mitlesen willst, solltest du wohl getline verwenden)zur aufgabe: mit charx > 97 und charx < 128 willst du wohl den bereich der buchstaben abdecken? dafür gibt es isalpha aus <cctype> afair.
bool is_uncapitalized_vowel (char c) { static const char vowels[] = "aeiou"; return find(vowels, vowels+5,c) != vowels+5; }dito für die switch anweisung. da statt den zahlen einfach schreiben
... case 'a' : vokale[0]++; break; case 'e' : vokale[1]++; break; ...allerdings ist die aufgabe
aufgabe schrieb:
die Konsonanten später aus der Differenz zwischen gesamtkleinenkonsonsnanten-vokalanzahl errechnet werden.
mir etwas unklar, musst du jetzt alle konsonanten zählen oder nur die kleingeschriebenen? however, auf jedenfall musst du immer daran denken, dass ein satz nicht nur aus buchstaben besteht.
Werner Salomon schrieb:
Mit strlen() wird dagegen zur Laufzeit jedesmal eine Funktion aufgerufen; diese Variante ist mit hoher Wahrscheinlichkeit langsamer.
vielleicht gibt es aber zaubercompiler, die wissen, dass in der schleife das char array nicht verändert wird, die würden das dann sicher vor die schleife ziehen. aber wer weiß...
-
Werner Salomon schrieb:
Caipi schrieb:
Dann solltest du statt cin >> satz; eher cin.getline(satz, 99); verwenden.
Hallo Caipi,
noch besser wäre die Verwendung eines Strings nebst der Funktion getline. Dann muss man sich nicht auf die (max.) Länge der Zeile festlegen.
std::string zeile; getline( std::cin, zeile );Jep. Hast natürlich Recht. Hab ich vergessen zu erwähnen.
Caipi schrieb:
Außerdem solltest du in der for-Schleife nicht sizeof(satz) / sizeof(char) verwenden, da deine Schleife sonst 100 mal durchlaufen wird. Nimm besser i < strlen(satz) als Abbruchbedingung.
Die Werte von 'sizeof(satz) / sizeof(char)' sind zur Compile-Zeit bekannt. Jeder durchschnittliche Compiler sollte aus diesem Ausdruck eine Konstante machen können. Mit strlen() wird dagegen zur Laufzeit jedesmal eine Funktion aufgerufen; diese Variante ist mit hoher Wahrscheinlichkeit langsamer.
Jup. Auch hier liegst du richtig. Habe mich allerdings falsch ausgedrückt (
). Ich meinte, dass der Schleifenkopf besser so aussehen sollte:for(unsigned int i = 0, e = strlen(satz); i < e; ++i)(Wobei das wahrscheinlich immer noch langsamer ist, als sizeof(satz) / sizeof(satz[0]).
Oder wenigstens das Array satz mit \0 initialisieren, damit die Werte nicht verfälscht werden. Dann kann der Schleifenkopf so stehen bleiben. (Darauf war mein Hauptaugenmerk beim posten gerichtet).
@davie: Keine Ahnung... liegt wohl daran, dass ich Arrays nocht nicht so oft mit Default-Werten initialisiert habe ;).
Gruß Caipi
-
hallo!
erstmal vielen dank für die zahlreichen antworten... leider ist das teilweise noch ein wenig hoch für mich^^ sry!!aufjedenfall wüsste ich jetzt mal gerne wie ich ganz einfach alle kleingeschriebenen konsonanten rausbekommen. weil ich kann ja doch auch mit euern lösungen keine zahlen mit den char-werten vergleichen, oder?
bin voll durcheinander grad

-
was meinst du mit "zahlen mit char werten vergleichen"? prinzipiell sind chars nichts anderes als zahlen.
char c = 'a'; c = 58; if (c == 'b') ; switch (c) { case 'a': ... }ist alles möglich.
eine funktion für kleingeschriebene konsonanten wäre z.b.
#include <algorithm> using namespace std; bool is_uncapitalized_consonant (char c) { static const char vowels[] = "bcdfghjklmnpqrstvwxyz"; return find(vowels, vowels+21, c) != vowels+21; }
-
ja ich mach ja:
if (satz[i] >= 97 && satz[i] <= 122)das scheint aber nicht zu gehen anscheinend. jedenfalls addiert er mir nichts dazu beim durchlaufen des satzes.
-
ViperNeo schrieb:
ja ich mach ja:
if (satz[i] >= 97 && satz[i] <= 122)das scheint aber nicht zu gehen anscheinend. jedenfalls addiert er mir nichts dazu beim durchlaufen des satzes.
Bei welchem Code? Bei dem von dir geposteten? Sollte mit den genannten Änderungen problemlos funktionieren.
Gruß Caipi