fgets() beendet frühzeitig
-
Guten Tag!
Ich bin auf ein Problem in einem Programm gestossen welches ich einfach nicht lösen kann. Ich habe bisher nur mit scanf gearbeitet, möchte nun aber einen String inklusive Leerzeichen einlesen. In der C Referenz hab ich fgets gefunden welche wohl meinen Bedürfnissen entspricht, wenn ich die fgets jedoch einsetze wartet das Programm auf keine Eingabe, sondern überspringt die Eingabe einfach.
Was gemacht werden soll: Einlesen eines Strings in ein Struct
Was momentan passiert: Eingabe des Strings wird übersprungenHier der Codeauszug (Problem in Zeile 21):
#include <stdio.h> struct Artikel { int num; // Artikelnummer char bez[20]; // Artikelbezeichnung float preis; // Artikelpreis int anz; // Anzahl Artikel }; struct Artikel liste[20]; int main() { int i=0; // Index printf("\nNeuen Eintrag erfassen, bitte Daten angeben:\n"); printf("\nArtikelnummer: "); scanf("%i", &liste[i].num); printf("Artikelname: "); fgets(liste[i].bez, 19, stdin); printf("Preis: "); scanf("%f", &liste[i].preis); printf("Anzahl: "); scanf("%i", &liste[i].anz); i++; printf("\nEingabe beendet"); }
Kann mir jemand auf die Sprünge helfen was ich da falsch mache?
Araex
-
Das "Problem" liegt bei scanf. Nach dem scanf bleibt das \n noch im Eingabebuffer liegen, welches anschliessen von fgets eingelesen wird.
Eine brauchbare lösung ist :while ((c = getchar()) != EOF && c != '\n');
nach dem scanf einzufügen.
-
Mal eine selten klare Fragestellung.
Du musst hinter jeder Eingabeabfrage den Eingabepuffer löschen, und dies natürlich standardkonform, z.B.int main() { int i=0; // Index printf("\nNeuen Eintrag erfassen, bitte Daten angeben:\n"); printf("\nArtikelnummer: "); scanf("%i", &liste[i].num); while(!feof(stdin)&&getchar()!='\n'); printf("Artikelname: "); fgets(liste[i].bez, 19, stdin); while(!feof(stdin)&&!strchr(liste[i].bez,'\n')&&getchar()!='\n'); printf("Preis: "); scanf("%f", &liste[i].preis); while(!feof(stdin)&&getchar()!='\n'); printf("Anzahl: "); scanf("%i", &liste[i].anz); while(!feof(stdin)&&getchar()!='\n'); i++; printf("\nEingabe beendet"); }
Bei zeichenweisem Einlesen via getchar/fgetc gilt das natürlich auch, ich verzichte aber hier mal auf ein Beispiel dazu.
Besser natürlich wäre es, eine universelle Eingabefunktion zum Einlesen eines Strings beliebiger Länge standardkonform zu implementieren und zu verwenden, wozu es auch bereits mehrere Lösungsvorschläge gäbe.
-
Binggi schrieb:
Eine brauchbare lösung ist :
while ((c = getchar()) != EOF && c != '\n');
nach dem scanf einzufügen.
Vielen Dank, funktioniert einwandfrei!
Darf ich mich erkundingen was das genau macht?
Solange der eingegebene char ungleich '\n' und End of File nicht erreicht ist wiederhole...? Was wiederholt die Schleife? Ich kenne while als "Während Bedingung X erfüllt, mache Y", das Y ist mir hier nicht klar.@Wutz,
Danke für deinen Vorschlag. Da kommen noch paar Dinge vor die ich noch nie genutzt habe, ich werd mich da mal durchlesen. Dann klärt sich vielleicht auch meine Unklarheit wegen dieser Whileschleife, denn du machst da ja was ähnliches.Danke
-
Wenn man es umschreibt ist es ev besser verständlich:
char c = getchar(); while (c!= EOF && c != '\n') c = getchar();
-
Araex schrieb:
Binggi schrieb:
Eine brauchbare lösung ist :
while ((c = getchar()) != EOF && c != '\n');
nach dem scanf einzufügen.
Vielen Dank, funktioniert einwandfrei!
Darf ich mich erkundingen was das genau macht?
Solange der eingegebene char ungleich '\n' und End of File nicht erreicht ist wiederhole...? Was wiederholt die Schleife? Ich kenne while als "Während Bedingung X erfüllt, mache Y", das Y ist mir hier nicht klar.Der Schleifenrumpf (also das, was Du Y nennst) ist in diesem Fall nur das Semikolon - die leere Anweisung.
-
Binggi schrieb:
Wenn man es umschreibt ist es ev besser verständlich:
char c = getchar(); while (c!= EOF && c != '\n') c = getchar();
Jetzt hab ichs verstanden.
Danke an alle!