2010-03-02 12 views
9

Ich bin ziemlich neu in C, und ich habe ein Problem mit der Eingabe von Daten in das Programm.Eingabe in C. Scanf wird vor. Problem

Mein Code:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main(void) { 
    int a; 
    char b[20]; 

    printf("Input your ID: "); 
    scanf("%d", &a); 

    printf("Input your name: "); 
    gets(b); 

    printf("---------"); 

    printf("Name: %s", b); 

    system("pause"); 
    return 0; 
} 

Es ermöglicht die Eingabe-ID, aber es springt nur den Rest des Eingangs. Wenn ich die Reihenfolge so ändere:

printf("Input your name: "); 
    gets(b); 

    printf("Input your ID: "); 
    scanf("%d", &a); 

Es wird funktionieren. Obwohl, ich kann nicht ändern Reihenfolge und ich brauche es so wie es ist. Kann mir jemand helfen ? Vielleicht muss ich einige andere Funktionen verwenden. Vielen Dank!

+1

bekommt (3): „Die gets() Funktion nicht sicher verwendet werden kann, wegen seiner fehlenden der Überprüfung der Grenzen, und die Unfähigkeit, für das aufrufende Programm. verlässlich ermitteln Sie die Länge der nächsten eingehenden Zeile, die Verwendung dieser Funktion ermöglicht es böswilligen Benutzern, eine laufende Programmfunktionalität durch einen Pufferüberlaufangriff beliebig zu ändern.Es wird dringend empfohlen, dass die Funktion fgets() verwendet wird alle c Asses. (Siehe die FSA.) " Verwenden Sie es nicht. –

+3

Kurz gesagt: Wenn Sie' gets' verwenden, wird fliegende tollwütige Angriff Ocelots Ihre Augenringe reißen. Also nicht. –

+2

'scanf' ist ** böse * * - http://c-faq.com/stdio/scanfprobs.html – jschmier

Antwort

10

Versuchen:.

scanf("%d\n", &a); 

nur bekommt liest die '\ n', die Blätter in scanf Außerdem sollten Sie fgets verwenden nicht bekommt: http://www.cplusplus.com/reference/clibrary/cstdio/fgets/ möglichen Pufferüberlauf zu vermeiden.

Edit:

wenn die oben nicht funktioniert, versuchen:

... 
scanf("%d", &a); 
getc(stdin); 
... 
+0

Hm. Ich habe versucht scanf ("% d \ n", &a); aber es scheint nicht zu funktionieren.Nachdem ich ID eingegeben habe, sehe ich einfach nicht, Programm sonst noch zu tun. – Dmitri

+0

Wow! Danke! Das funktionierte einwandfrei! Danke für Ratschläge über Fgets. Wird es sicherlich verwenden !! Vielen Dank! – Dmitri

7

scanf nicht die Newline verbrauchen und ist somit ein natürlicher Feind von fgets. Verbinde sie nicht ohne einen guten Hack. Beide Optionen funktionieren:

// Option 1 - eat the newline 
scanf("%d", &a); 
getchar(); // reads the newline character 

// Option 2 - use fgets, then scan what was read 
char tmp[50]; 
fgets(tmp, 50, stdin); 
sscanf(tmp, "%d", &a); 
// note that you might have read too many characters at this point and 
// must interprete them, too 
+0

Super !! Vielen Dank! – Dmitri

+0

Außerdem sollte 'scanf ("% d% * c ", & a)' funktionieren. Der Ausdruck "% * c" bewirkt, dass "scanf" in einem Zeichen (der neuen Zeile) gelesen wird, aber der Stern bewirkt, dass der Wert verworfen wird. Dies führt dazu, dass "scanf" die Zeilenschaltung isst, ohne dass ein separater Funktionsaufruf erforderlich ist. – bta

+0

Sie präsentieren beide Optionen so, als wären sie gleichberechtigt, aber 'scanf' ist nur so schwer zu benutzen, dass es viel besser ist, es komplett zu benutzen (siehe den comp.lang.c FAQ Link). Einfach mit Option 2 gehen. – jamesdlin

1
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main(void) { 
     int a; 
     char b[20]; 
     printf("Input your ID: "); 
     scanf("%d", &a); 
     getchar(); 
     printf("Input your name: "); 
     gets(b); 
     printf("---------"); 
     printf("Name: %s", b); 
     return 0; 
} 



Note: 
    If you use the scanf first and the fgets second, it will give problem only. It will not read the second character for the gets function. 

    If you press enter, after give the input for scanf, that enter character will be consider as a input f or fgets. 
2

Scanf nicht verbrauchen \ n so wird es gemacht werden, indem man das bekommt, die die scanf folgt. Leeren Sie den Eingabestrom nach scanf wie folgt.

#include <stdlib.h> 
#include <string.h> 

int main(void) { 
    int a; 
    char b[20]; 

    printf("Input your ID: "); 
    scanf("%d", &a); 
    fflush(stdin); 
    printf("Input your name: "); 
    gets(b); 

    printf("---------"); 

    printf("Name: %s", b); 

    system("pause"); 
    return 0; 
} 
+2

Sowohl fflush (stdin) als auch fflush (NULL), in einigen C-Bibliotheken, werden stdout und stderr spülen, aber das ist komplett nicht portierbar! –

0

sollten Sie diesen Weg gehen.

fgetc(stdin); 
    scanf("%c",&c); 
    if(c!='y') 
    { 
     break; 
    } 
    fgetc(stdin); 

zum Lesen von Eingabe von scanf nach dem Lesen durch gets.

0

verwenden Nur 2 gets() funktioniert

Wenn Sie verwenden möchten, gets() nach einer scanf(), stellen Sie sicher, dass Sie verwenden 2 von der gets() Funktionen und für den obigen Fall schreiben Sie Ihren Code wie:

int main(void) { 
    int a; 
    char b[20]; 

    printf("Input your ID: "); 
    scanf("%d", &a); 

//the change is here********************* 
    printf("Input your name: "); 
    gets(b); 
    gets(b); 
//the change is here********************* 

    printf("---------"); 

    printf("Name: %s", b); 

    system("pause"); 
    return 0; 
} 

Zur Erklärung ([email protected]);

+0

Willkommen in SO! Bitte denken Sie daran, dass Englisch hier nicht die erste Sprache ist. Versuchen Sie daher, grammatikalisch korrekte Antworten zu posten, anstatt "du" zu verwenden - was nicht mit Google Übersetzer funktioniert! –

0

scanf("%d", &a); kann die Rückgabe nicht lesen, da %d nur Dezimalzahl akzeptiert. Sie fügen also einen \n am Anfang des nächsten scanf hinzu, um den letzten \n innerhalb des Puffers zu ignorieren.

Dann kann scanf("\n%s", b); jetzt die Zeichenfolge ohne Problem lesen, aber scanf stoppt, um zu lesen, wenn Sie einen Leerraum finden. Also, ändern Sie die %s zu %[^\n].Es bedeutet:

scanf("\n%[^\n]", b);

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main(void) { 
    int a; 
    char b[20]; 

    printf("Input your ID: "); 
    scanf("%d", &a); 

    printf("Input your name: "); 
    scanf("\n%[^\n]", b); 
    //first \n says to ignore last 'return' 
    //%[^\n] read until find a 'return' 
    printf("---------\n"); 
    printf("Name: %s\n\n", b); 

    system("pause"); 
    return 0; 
} 
+1

Bitte fügen Sie eine Erklärung des Codes hinzu. – coatless

+0

Explantation hinzugefügt @ Coatless –

0

Die scanf Funktion Leerzeichen „Everthing aber \n lesen“ entfernt automatisch, bevor andere Dinge als Zeichen zu analysieren versucht. %c, %n, %[] sind Ausnahmen, die führende Leerzeichen nicht entfernen.

gets liest den Zeilenvorlauf von vorherigen scanf. Fangen Sie die Newline mit getchar();

scanf("%d", &a); 
getchar(); // catches the newline character omitted by scanf("%d") 
gets(b); 

https://wpollock.com/CPlus/PrintfRef.htm