scanf



  • Hey Leute,

    hab ein Problem bei folgendem Programm:

    #include <stdio.h>
    
    int main(){
    	char Zeichen;
    
    	while(1){
    		printf("Eingabe: ");
    		scanf("%c",&Zeichen);
    
    		if(Zeichen=='q')
    			break;		
    
    		printf("\nAusgabe: %d\n",(int)Zeichen);
    	}
    
    }
    

    und zwar soll das Programm zu einem eingegebenem ASCII-Zeichen den dezimalen ASCII-Wert ausgeben.

    Soweit so gut, mein Problem ist nun aber, dass scanf bei Eingabe einer Zeichenfolge(dafür ist das Programm eigentlich nicht dacht, trotzdem wundert mich der Fehler), im ersten Durchgang nur das erste Zeichen ein "Zeichen" einliest (was auch so gewünscht ist) jedoch beim nächsten Durchlauf der while-Schleife ohne auf eine Eingabe zu warten direkt das nächste Zeichen aus der anfangs eingebenen Zeichenkette in Zeichen speichert.

    Also kurz gesagt, wenn ich dem Programm sowas wie xx Angebe, dann kommt als Ausgabe sowas wie:

    Eingabe: xx
    Ausgabe: 120
    Eingabe:
    Ausgabe: 120

    Kann mir das evtl jemand von euch erklären? Normal müsste sowas wie scanf("%c",&Zeichen) nur ein Zeichen einlesen, weil ein char auf meinem Rechner nur 1Byte groß ist oder nicht?

    Gruß



  • Vor der Eingabe den Eingabepuffer leeren, z.B. so:

    char c;
    while((c=getchar())!=EOF && c!='\n');
    


  • Geht das nicht auch so:

    fflush(stdin);
    


  • gary1195 schrieb:

    Geht das nicht auch so:

    fflush(stdin);
    

    Nein.
    🙂

    Edit:
    Lies mal hier weiter:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-39349.html



  • mngbd schrieb:

    gary1195 schrieb:

    Geht das nicht auch so:

    fflush(stdin);
    

    Nein.
    🙂

    Undefined Behaviour
    (:



  • gary1195 schrieb:

    Geht das nicht auch so:

    fflush(stdin);
    

    Beim MS-Compiler ist es erlaubt und kein nicht definiertes Verhalten. Aber da es nicht standardkonform ist (und sich das im Grunde mit dem nächsten MS-Compiler einfach ändern kann), sollte man besser einen anderen Weg wählen.



  • Noch was:

    scanf("%c",&Zeichen);
    // besser:
    Zeichen = getchar();
    

    MatheStein schrieb:

    Normal müsste sowas wie scanf("%c",&Zeichen) nur ein Zeichen einlesen, weil ein char auf meinem Rechner nur 1Byte groß ist oder nicht?

    Ein char ist immer 1 Byte gross.
    🙂



  • _matze schrieb:

    Vor der Eingabe den Eingabepuffer leeren, z.B. so:

    char c;
    while((c=getchar())!=EOF && c!='\n');
    

    Wenn das zuverlässig funzen soll, muss der Typ int sein, d.h.

    int c;
    

    Gruß,
    B.B.



  • wie ist stdin überhaupt spezifiziert?

    Das muss ja schon irgendwie über einen Handel angesprochen werden (oder etwas ähnliches) da scanf sich sequentiell durch den dafür hinterlegen "stdin-Puffer" arbeitet.
    Wie wird der stdin-Puffer geleert? Nur beim auslesen der einzelnen Elemente oder Beenden des Prozesses? Oder löscht das BS den Inhalt nach einer gewissen Zeit selbst? Kann mir da jetzt ehrlichgesagt nicht viel drunter vorstellen und das ganze nicht wirklich einordnen

    Gruß und schönen Abend 🙂



  • MatheStein schrieb:

    wie ist stdin überhaupt spezifiziert?

    stdin ist ein Makro, das zu einem Zeiger auf eine FILE -Struktur evaluiert, die den Standard-Ausgabe-Stream des System repräsentiert.

    MatheStein schrieb:

    Das muss ja schon irgendwie über einen Handel angesprochen werden

    Der ist üblicherweise 0. Aber das hat nichts mit C zu tun.

    MatheStein schrieb:

    Wie wird der stdin-Puffer geleert?

    Ein Trick, mit dem man alles, was gerade da drin ist, löschen kann, steht hier:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-111042.html
    🙂



  • mngbd schrieb:

    Ein Trick, mit dem man alles, was gerade da drin ist, löschen kann, steht hier:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-111042.html
    🙂

    Die setvbuf Variante kann funktionieren, muss aber nicht. Hier hat mal jemand gepostet, bei dem das nicht funktioiniert hat.

    Gruß,
    B.B.



  • anstatt scanf zu benutzen, fgets/getc verwenden und mit sscanf parsen. Das erspart den ganzen "stdin-leeren"-Ärger.



  • supertux schrieb:

    anstatt scanf zu benutzen, fgets/getc verwenden und mit sscanf parsen. Das erspart den ganzen "stdin-leeren"-Ärger.

    Auch wenn man fgetc benutzt, können Zeichen im Eingabepuffer übrig bleiben.



  • BiG Brazz0r schrieb:

    mngbd schrieb:

    Ein Trick, mit dem man alles, was gerade da drin ist, löschen kann, steht hier:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-111042.html
    🙂

    Die setvbuf Variante kann funktionieren, muss aber nicht. Hier hat mal jemand gepostet, bei dem das nicht funktioiniert hat.

    Hast völlig recht. Und ich hab das immer geglaubt... 🙄

    C99 TC2 7.19.5.6 schrieb:

    The setvbuf function may be used only after the stream pointed to by stream has
    been associated with an open file and before any other operation (other than an
    unsuccessful call to setvbuf) is performed on the stream.

    Klingt ziemlich eindeutig. Blöd nur, dass dort nur Moderatoren posten dürfen.
    🙂



  • BiG Brazz0r schrieb:

    supertux schrieb:

    anstatt scanf zu benutzen, fgets/getc verwenden und mit sscanf parsen. Das erspart den ganzen "stdin-leeren"-Ärger.

    Auch wenn man fgetc benutzt, können Zeichen im Eingabepuffer übrig bleiben.

    ja, das stimmt, aber seitdem ich fgetc/fgets verwende, musste ich das noch kein einziges Mal machen. 😉



  • mngbd schrieb:

    Klingt ziemlich eindeutig. Blöd nur, dass dort nur Moderatoren posten dürfen.
    🙂

    Ja, der o.a. FAQ-Beitrag hat noch ein paar andere Fehler.

    Blöderweise scheint nie ein Moderator mitzulesen, wenn ich das anmerke
    (Hint: Dies ist bereits Versuch Nr. 1726 :D)



  • Vorschlag: erstelle einen neuen Thread mit korrigiertem Inhalt, sende mir den Link per Email, und "faqe" das und entferne den alten FAQ-Thread.



  • Marc++us schrieb:

    Vorschlag: erstelle einen neuen Thread mit korrigiertem Inhalt, sende mir den Link per Email, und "faqe" das und entferne den alten FAQ-Thread.

    Am besten gleich hier anhängen:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-263283.html

    Ich kann das nämlich nicht selbst machen, weil ich dort sonst keinen Fehler mehr gefunden hab.
    🙂


Anmelden zum Antworten