C-Neuling(lerne gerade) - Schleifen und Bedingungen werden nicht richtig abgearbeitet
-
Joar hi@all,
ich bin dabei mich in die Programmiersprache c einzuarbeiten und wollte ein kleines sinnlos Programm schreiben welches ich ständig mit neuem Wissen erweitern möchte. Leider hab ich schon am Anfang Probleme die ich nicht verstehe(bei denen ich nicht weiß wie Sie entstehen können und wie ich sie beseitigen kann)#include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { typedef struct{ char Titel[20]; char Interpret[20]; char Gelernt; } tLieder; tLieder Lieder[100]; int a=0, i; char b; printf("Willkommen in ihrer Musikbibliothek!\n"); do{ printf("\nBitte geben Sie jetzt den Musiktitel ein:\n"); for (i=0; (Lieder[a].Titel[i]=getchar()) != '\n' && i<=19; i++); //<--Eingabe auf Variable legen for (; i<=19; i++) Lieder[a].Titel[i]=' '; //<--Standardlänge von 20 Feldern für spätere Tabelle printf("\nBitte geben sie den Interpreten an:\n"); for (i=0; (Lieder[a].Interpret[i]=getchar()) != '\n' && i<=19; i++); //<--Eingabe auf Variable legen for (; i<=19; i++) Lieder[a].Interpret[i]=' '; //<--Standardlänge von 20 Feldern für spätere Tabelle printf("\nHaben sie diesen Titel gelernt?(Y-Ja, N-Nein)\n"); Lieder[a].Gelernt=getchar(); printf("\nMoechten Sie noch einen Eintrag machen?(Y-Ja, N-Nein)\n"); do{ b=getchar(); if(b!='Y' && b!='N') printf("ungueltige Eingabe\n"); }while (b!='Y' && b!='N'); a++; }while(b=='Y'); /*Tabellenausgabe*/ printf("\n"); printf("Titel Interpret Gelernt\n"); while(a>0){ for (i=0; i<=19; i++) printf("%c",Lieder[a-1].Titel[i]);//<--Ausgabe Liedtitel for (i=0; i<=19; i++) printf("%c",Lieder[a-1].Interpret[i]);//<--Ausgabe Interpret printf("%c",Lieder[a-1].Gelernt); printf("\n"); a--; } system("PAUSE"); return 0; }
ich würde mir wünschen wenn ihr das kurz testen würdet und mir dann sagen was ich falsch mache da ich den Fehler nicht nachvollziehen kann!
thx before
mfg
foerster7891
-
Nach flüchtigem Blick kann ich mir schon denken, woran es hapert, hier ist es aber eigentlich üblich, den Fehler zu beschreiben, bei welchem wir dir helfen sollen.
-
k dann:
wenn ich einmal die erste Reihe der Tabelle abgearbeitet habe, also Titel, Interpret, Gelernt, dann soll er fragen ob ich einen weiteren Eintrag machen möchte!
Daraufhin blendet er allerdings sofort ungültige Eingabe ein, wenn ich dann danach mit Y antworte kommt die Frage nach dem Musiktitel und direkt danach ohne die Möglichkeit etwas einzugeben die Frage nach dem Interpreten. Wenn ich N antwortet er wie gewollt mit der Ausgabe der Tabelle.Allerdings kann ich mir diese Fehler nicht erklären.
PS.: Falls ich irgendetwas falsch formuliert, irgendwelche erforderlichen WICHTIGEN Angaben nicht gemacht habe weißt mich bitte daraufhin. Ich möchte wirklich Hilfe haben^^^. THX
-
Das Problem war, dass du die zeichenweise Eingabe viá getchar()/scanf("%c"...) verwendest, wobei es zu Eingabepufferproblemen kommt, die durch nachfolgende Abfrage durchschlagen. Ich habe mal die char-Array(=String) Variante gezeigt, die sollte bei richtigem Gebrauch funktionieren und kann auch die von dir gezeigte Bereichsgrenzenprüfung übernehmen. Weiterhin kanntest du offensichtlich die Formatangaben bei printf/scanf nicht, du hättest dir einige Schreibarbeit sparen können wie du siehst
typedef struct{ char Titel[20]; char Interpret[20]; char Gelernt[2]; } tLieder; main() { tLieder Lieder[100]; int a=0,i; char b[2]; puts("Willkommen in ihrer Musikbibliothek!"); do{ printf("\nBitte geben Sie jetzt den Musiktitel ein:\n"); while( 1!=scanf("%19s",Lieder[a].Titel) ); //<--Eingabe auf Variable legen printf("\nBitte geben sie den Interpreten an:\n"); while( 1!=scanf("%19s",Lieder[a].Interpret) ); //<--Eingabe auf Variable legen printf("\nHaben sie diesen Titel gelernt?(Y-Ja, N-Nein)\n"); while( 1!=scanf("%1s",Lieder[a].Gelernt) ); //<--Eingabe auf Variable legen ++a; puts("\nMoechten Sie noch einen Eintrag machen?(Y-Ja, N-Nein)"); }while( scanf("%1s",b), *b=='Y' && a+1<sizeof Lieder ); /*Tabellenausgabe*/ printf("\n%-20s%-20s%1s\n","Titel","Interpret","Gelernt"); for(i=0;i<a;++i) printf("%-20s%-20s%1s\n",Lieder[i].Titel,Lieder[i].Interpret,Lieder[i].Gelernt); system("PAUSE"); return 0; }
-
K danke erstmal aber ich werd dich jetzt einfach mal mit Fragen bombadieren!
Wie zeigen sich diese Eingabepufferprobleme/wodurch entstehen diese?
Warum wird char Gelernt in char Gelernt[2] und b in b[2] es soll ja eigl nur ein char eingegeben werden! Ein eventuell folgendes \n soll ja nicht als char mit gelesen werden!
Was ist der Unterschied zwischen puts und printf?
Die erste und die beiden darauf folgenden while-Schleifen enthalten als Bed. 1!=scanf wird damit die Stringlänge abgefragt?
%19s - steht das für 19 Stellen für einen Eintrag und das s für string?
Und müsste es bei "while( scanf("%1s",b), *b=='Y' && a+1<sizeof Lieder );" nicht eigentlich a<sizeof Lieder heißen heißen?Ich hoffe ich bekomme die Fragen beantwortet auch wenn man sie sicher mit Tutorials pauken alle beantworten könnte^^.
-
In ANSI C gibt es nur die asynchrone, d.h. gepufferte Eingabeauswertung, welche bis Eintreffen von '\n' alles einliest, was kommt.
scanf("%c"...) und getchar() lesen nur 1 Zeichen und entfernen auch nur 1 Zeichen aus dem o.g. Eingabepuffer, d.h. '\n' bleibt im Eingabepuffer und wird vo einem evtl. folgenden scanf("%"...) oder getchar() als Eingabezeichen ausgewertet, schlägt also quasi "durch", was meistens nicht beabsichtigt ist. char-Array Eingaben scanf("%s")/fgets haben diese Begrenzung nicht und lassen '\n' nicht im Eingabepuffer stehen.
Es gibt verschiedene Versuche, eine synchrone Eingabeauswertung zu implementieren wie kbhit() usw. ist aber kein C89 Standard und IMHO auch nicht in C99.
Deshalb müssen Gelernt und b auch 2 Zeichen lang sein, für 1 gelesenes Zeichen + 1 abschließendes '\0'.
puts(bla) entspricht printf("%s\n",bla)
scanf gibt als Returnwert die Anzahl gemäß Format erfolgreich gelesenen und zugewiesenen Werte zurück, while liest also solange, bis die vorgegebene Bedingung erfüllt ist.
ja
muss a<sizeof Lieder heissen, war Fehler von mir