Problem mit struct, Felder, scanf
-
Hallo!
Ich habe ein Problem mit folgendem Code, den ich für eine Informatik-Übung benötige. Ich würde gerne die Daten Titel, Interpret, Dauer und Erscheinungsjahr einer CD mit scanf eingeben können. Jedoch funktioniert das nicht so, wie ich es mir vorstelle. Die Typen müssten doch passen, oder?
Hier, was mir Eclipse ausgibt:
Album-Titel angeben: Testtitel
Interpret angeben: Testinterpret
Spielzeit (in Minuten) angeben: 123
Erscheinungsjahr angeben: 2000
Ausgabe: T ... { ... 123 ... 2000Und hier der Code:
#include <stdio.h> int main(void) { struct musikdb { char titel[80]; char interpret[80]; int dauer; int erscheinungsjahr; }cd; printf("Album-Titel angeben: "); scanf("%s",cd.titel); printf("Interpret angeben:" ); scanf("%s",cd.interpret); printf("Spielzeit (in Minuten) angeben: "); scanf("%i",&cd.dauer); printf("Erscheinungsjahr angeben: "); scanf("%i",&cd.erscheinungsjahr); printf("%c ... %c ... %i ... %i",cd.titel[80],cd.interpret[80],cd.dauer,cd.erscheinungsjahr); return(0); }
-
Das Ding für Strings heißt
%s
und nicht%c
.cd.titel[80],cd.interpret[80]
Die Größe eines Arrays muss man nicht bei jeder Verwendung angeben.
-
Bitte löschen
-
Oh, Tatsache. Das ist wohl noch ein Überbleibsel von diversen Versuchen, das Problem lösen zu wollen. Da hätte ich noch so oft suchen können, ich hätte das wohl nie gefunden. Die Feldgröße habe ich auch rausgenommen. Jetzt funktioniert es. Vielen Dank!
Edit:
Nächstes Problem: Leerzeichen. Folgende Information ist vom Prof gegeben:Einlesen einer Zeichenkette mit scanf, die aus mehreren Worten besteht, kann folgendermaßen durchgeführt werden:
char name[80];
char dummy;
scanf("%[^\n]",name); /* Alle Zeichen ausser Returnzeichen einlesen*/
scanf("%c",&dummy); /* Returnzeichen aus dem Eingabepuffer herauslesen*/Ich kann die Angabe nicht richtig deuten. Wie genau bringe ich das unter? Anstatt
printf("Album-Titel angeben: "); scanf("%s",cd.titel);
folgendes zu nutzen
printf("Album-Titel angeben: "); scanf("%[^\n]",cd.titel);
funktioniert zumindest nicht. Da bekomme ich nur murks raus... Und wie gehe ich mit dem Dummy um? Wenn die beiden dazu gegebenen Zeilen mit in den Code einbaue, tut sich auch nichts sinnvolles.
-
Doppelt aufpassen bei
scanf("%s"
Hier sollte eine Bereichsgrenze vorgegeben werden, auch bricht scanf beim 1 Whitespace ab, d.h. keine Leerzeicheneingaben sind möglich
-
Bereichsgrenze? Wie ist das gemeint?
Diese Möglichkeit hinter dem Link habe ich auch schon mehrmals gesehen. Wir haben das jedoch noch nicht durchgenommen. Ich muss mich also wohl mit folgendem arbeiten:
scanf("%[^\n]",name);
-
Mache was du nicht lassen kannst.
Komme nachher aber nicht wieder an mit Aussagen wie: "Mein Programm funktioniert mal und dann wieder nicht..." o.ä.
Die gezeigte Lösung ist strikt ANSI C und somit maximal portabel, und arbeitet für jede erdenkliche Nutzereingabe.
-
Wutz schrieb:
Mache was du nicht lassen kannst.
Mh, ich würde es anders ausdrücken: Ich mache nicht, was ich noch nicht durchgenommen habe bzw was ich nicht kenne
Ich denke, gerade im Studium, wo man im Prinzip nur auf die Prüfungen hinlernt, kann man sich diese Einstellung leisten. Klar, Alternativvorschlägen bin ich immer dankbar. Aber ich würde es dennoch bevorzugen, die Lösung zu verwenden, die vom Professor gefordert ist.
Wutz schrieb:
Komme nachher aber nicht wieder an mit Aussagen wie: "Mein Programm funktioniert mal und dann wieder nicht..." o.ä.
Die gezeigte Lösung ist strikt ANSI C und somit maximal portabel, und arbeitet für jede erdenkliche Nutzereingabe.Wenn es später nicht funktionieren sollte, dann werde ich ziemlich sicher wieder ins Forum kommen! Dazu ist das Forum ja da. Würde dir in diesem Fall empfehlen, einfach nicht reinzulesen
Mein Professor wird schon beachtet haben, inwiefern das Programm ausgereizt werden soll. Ich denke, die Portabilität steht eher im Hintergrund.
-
muesteff schrieb:
Bereichsgrenze? Wie ist das gemeint?
Diese Möglichkeit hinter dem Link habe ich auch schon mehrmals gesehen. Wir haben das jedoch noch nicht durchgenommen. ...
Im Studium ist durchaus Eigeninitiative gefragt.
Wenn du mehr weißt/anwendest als ihr durch genommen habt ist es ja nicht falsch.
-
Ich würde dennoch gerne die gegebene Methode verwenden. Einfach aus dem Grund, da es ein Vorschlag vom Professor ist
Ist doch sicherlich auch verständlich?
-
muesteff schrieb:
Bereichsgrenze? Wie ist das gemeint?
scanf hat keine Ahnung, wieviel Platz für die Eingabe zur Verfügung steht, deshalb schreibt es so lange weiter, wie es Platz benötigt. Das kann ins Auge gehen, wnn die Eingabe länger ist als das Array, das zu übergeben hast. Als Lösung kannst du angeben, wieviel Platz du zur Verfügung hast:
scanf("%79s",cd.titel); //bzw. scanf("%79[^\n]",cd.titel);
(außerdem solltest du dir eventuell die übrigen Funktionen aus der <stdio.h> ansehen - fgets() und und fgetc() sind das sehr hilfreich ;))
-
Ah, ok. Danke für die Erklärung! Habe meinen Code entsprechend erweitert:
#include <stdio.h> int main(void) { struct musikdb { char titel[80]; char interpret[80]; int dauer; int erscheinungsjahr; }cd; printf("Album-Titel angeben: "); scanf("%79[^\n]",cd.titel); printf("Interpret angeben: "); scanf("%79[^\n]",cd.interpret); printf("Spielzeit (in Minuten) angeben: "); scanf("%i",&cd.dauer); printf("Erscheinungsjahr angeben: "); scanf("%i",&cd.erscheinungsjahr); printf("Ausgabe: %s ... %s ... %i ... %i",cd.titel,cd.interpret,cd.dauer,cd.erscheinungsjahr); return(0); }
Beim Ausführen bekomme ich jedoch ein seltsames Problem: Den Album-Titel kann ich eingeben, auch Leerzeichen werden korrekt in cd.titel geschrieben. Wenn ich den Alben-Titel eingegeben habe und ENTER drücke, kommt: "Interpret eingeben: Spielzeit (in Minuten) eingeben:" also quasi beide gleichzeitig. Das erscheint auch unabhängig davon, ob ich einen Alben-Titel mit oder ohne Leerzeichen eingebe. Woher kommt das?
-
Das liegt daran, daß nach der Eingabe des Titels noch das Enter darauf wartet, eingelesen zu werden - das ist also das erste Zeichen, das der nächste scanf-Aufruf findet (der sofort abbricht und einen leeren String liest). Die Lösung hat dir schon dein Professor genannt -
scanf("%c",&dummy);
oderfgetc(stdin);
liest genau dieses überflüssige Enter ein und du kannst mit der nächsten Eingabe fortsetzen.
(noch sauberer ist:while(fgetc(stdin)!='\n');
- schließlich mußt du auch damit rechnen, daß die Eingabe nicht wegen des Zeilenendes abgebrochen wurde, sondern wegen Platzmangel)
-
Vielen herzlichen Dank, CStoll! Super Hilfestellung und klasse Erklärung. Programm läuft!
-
CStoll schrieb:
(noch sauberer ist:
while(fgets(stdin)!='\n');
- schließlich mußt du auch damit rechnen, daß die Eingabe nicht wegen des Zeilenendes abgebrochen wurde, sondern wegen Platzmangel)
Nicht sauber sondern falsch.