Problem mit scanf() und fgets()



  • Hallo,
    Da ich zurzeit recht neu in programmieren bin und die Werte nacheinander einlesen möchte stoße ich auf folgendes Problem. Zum einen überspringt es eine Zeile und zum anderen kommen irsinnige Werte raus obwohl ich komplett was anderes eingelesen habe.

    Natürlich ist das nur einfaches Beispiel unten , aber wie kann man das am besten korriegeren? Selbst mit fflush(stdin) was ja bekanntlicherweise die Eingabepuffer löscht funktioniert bei den neuen compiler nicht.
    Also ich würd mich über jede Erklärung und Hilfe freuen ! Danke !

    int main() {
    	char ISBN[20], Titel[50], Autor[30];
    	double preis;
    	int Anzahl;
    
    	printf("ISBN Nummer : ");
    	scanf("%s", &ISBN);
    	printf("Titel : ");
    	fgets(Titel, 50, stdin);
    	printf("Autor :");
    	fgets(Autor, 30, stdin);
    	printf("Preis :");
    	scanf("%lf", &preis);
    	printf("Anzahl :");
    	scanf("%i", &Anzahl);
    
    	printf("ISBN Nummer : %s\n", &ISBN);
    	printf("Titel : %s\n", &Titel);
    	printf("Autor : %s\n", &Autor);
    	printf("Preis : %lf\n", &preis);
    	printf("Anzahl: %i\n", &Anzahl);
    }
    

    Die Eingabe war wie folgt : ISBN Nummer : 1111111111
    Titel : Autor : Hallo
    Preis : 29.99
    Anzahl: 5

    Die Ausgabe sah dann so aus : ISBN Nummer : 1111111111
    Titel :
    Autor : Hallo
    Preis : 0.000000
    Anzahl: 8190844



  • fgets ist meines wissens nach nur für Dateiströme.
    Verwende doch einfach scanf.

    Wer lehrt denn sowas das fgets zum Tastatureingaben abzugreifen verwendet wird?



  • scanf hab ich fast genau die selben Probleme , und ich kann damit keine Leerzeichen lesen...



  • - fflush+stdin ist Schrott
    - die Mischung von fgets+scanf ist Schrott

    - die kürzeste Lösung (mit 2 Einschränkungen) ist:
    - jeweils 1x fgets und 1x sscanf anschließend

    char tmp[100];
    
    fgets(tmp,100,stdin);
    if( sscanf(tmp,"%19[^\n]",ISBN)!=1 ) puts("fehler");
    fgets(tmp,100,stdin);
    if( sscanf(tmp,"%49[^\n]",Titel)!=1 ) puts("fehler");
    fgets(tmp,100,stdin);
    if( sscanf(tmp,"%29[^\n]",Autor)!=1 ) puts("fehler");
    fgets(tmp,100,stdin);
    if( sscanf(tmp,"%lf",&preis)!=1 ) puts("fehler");
    fgets(tmp,100,stdin);
    if( sscanf(tmp,"%d",&Anzahl)!=1 ) puts("fehler");
    

    die Einschränkungen sind:
    - gibt der User mehr als 99 Zeichen ein, muss stdin extra geleert werden
    - Leereingaben werden ignoriert/nicht als Fehler ausgewertet



  • also fflush(stdin) funktioniert nur unter windows und printf bekommt normalerweise keine adressen übergeben - außer natürlich, man möchte auch die adressen ausgeben. 😉

    achja und dass eine eingabe übersprungen wird, liegt eben daran, dass da noch das "enter-zeichen" im eingabepuffer liegt, also eingabepuffer leeren mit fflush(stdin) (nur unter windows) oder einmal getchar() aufrufen.



  • HansKlaus schrieb:

    ... und printf bekommt normalerweise keine adressen übergeben - außer natürlich, man möchte auch die adressen ausgeben. 😉

    Sobald man den Formatspecifier %s hat, erwartet printf eine Adresse.
    Und da möchte man keine Adresse ausfgeben.

    Allerdings ist der Adressoperator bei Arrays überflüssig - und wenn man das Array durch einen Zeiger ersetzt sogar falsch.

    Bei char ISBN[20]; liefern ISBN und &ISBN zwar denselben Wert, der Typ ist jedoch anders.
    ISBN liefert einen Zeiger auf char
    &ISBN liefert einen Zeiger auf ein Array 20 aus char Zeiger auf char http://cdecl.org/?q=char+%28*c%29%5B20%5D

    Der Unterschied macht sich bei der Zeigerarithmetij bemerkbar.
    ISBN+1 liefert das zweite Element von ISBN
    (&ISBN)+1 liefert das Element hinter ISBN (da wird +20 gerechnet)



  • Ja aber printf("%lf",&preis) ist eindeutig falsch und das Ergebnis lautet zu recht 0.000000 und printf("%i",&anzahl) liefert doch sogar eine Ausgabe.



  • Jupp.

    Dann ist aber der Adressoperator bei printf in fast allen Fällen falsch.
    (und nicht die Übergabe von Adressen)



  • naja das ist jetzt auslegungssache, ob man bei einem array eben das array übergibt, oder die adresse des ersten elements, bzw. bei einem zeiger eben den wert der zeigervariable, oder die adresse des elements, auf das der zeiger verweist.

    ich für mich übergebe jedenfalls adressen, wenn ein & davor steht, und werte, wenn kein & davor steht.


  • Mod

    Wie Arrays in C funktionieren ist aber keine Auslegungssache. Es ist bloß etwas, das viele Anfänger nicht wissen.



  • HansKlaus schrieb:

    naja das ist jetzt auslegungssache, ob man bei einem array eben das array übergibt, oder die adresse des ersten elements,

    Da man in C keine kompletten Arrays (ohne Kunstgriff) übergeben kann, übergibt man die Adresse des ersten Elements. Dafür steht nämlich der Arrayname. Ohne Adressoperator

    HansKlaus schrieb:

    bzw. bei einem zeiger eben den wert der zeigervariable, oder die adresse des elements, auf das der zeiger verweist.

    Das ist ja identisch.

    HansKlaus schrieb:

    ich für mich übergebe jedenfalls adressen, wenn ein & davor steht, und werte, wenn kein & davor steht.

    Das haut bei Zeigern ja schon mal nicht hin, da der Wert eines Zeigers ja eine Adresse ist.



  • Sehr amüsant, es gibt hier niemanden, der so von sich überzeugt ist und gleichzeitig so oft korrigiert werden muss, wie HansKlaus.
    Bedenk bitte Kläuschen, hier lesen auch Kinder! Die sollen weder denken, dass man so programmiert noch soviel 3/4-Wissen überzeugt zum "Besten" gibt!


Log in to reply