2010-03-02 4 views
9

Je suis assez nouveau pour C, et j'ai un problème avec la saisie de données dans le programme.Entrée dans C. Scanf avant obtient. Problème

Mon 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; 
} 

Il permet d'ID d'entrée, mais il saute tout simplement le reste de l'entrée. Si je change la commande comme ceci:

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

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

Cela fonctionnera. Bien que, je ne peux pas changer l'ordre et j'en ai besoin tel quel. Est-ce que quelqu'un peut m'aider ? Peut-être que j'ai besoin d'utiliser d'autres fonctions. Merci!

+1

obtient (3): « Le gets() fonction ne peut pas être utilisé en toute sécurité En raison de son manque de limites de contrôle, et l'incapacité pour le programme appelant. détermine de manière fiable la longueur de la prochaine ligne entrante, l'utilisation de cette fonction permet aux utilisateurs malveillants de modifier arbitrairement la fonction d'un programme en cours par le biais d'une attaque de débordement de mémoire tampon Il est fortement recommandé d'utiliser la fonction fgets() dans tout c ases. (Voir la FSA.) " Ne l'utilisez pas –

+3

Plus brièvement: Si vous utilisez' gets', les ocelots de l'attaque rabique volante vous déchireront les orbites, alors ne le faites pas –

+2

'scanf' est ** evil * * - http://c-faq.com/stdio/scanfprobs.html – jschmier

Répondre

10

Essayez:.

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

obtient lit seulement le '\ n' que Scanf feuilles en outre, vous devez utiliser fgets n'obtient: http://www.cplusplus.com/reference/clibrary/cstdio/fgets/ pour éviter les dépassements de tampon possibles.

Edit:

si le ne fonctionne pas, essayez:

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

Hm. J'ai essayé scanf ("% d \ n", &a); mais il ne semble pas fonctionner.Après avoir entré l'ID, je ne vois pas le programme faire quoi que ce soit d'autre – Dmitri

+0

Wow! Merci! Cela a fonctionné sans faille! Merci pour les conseils sur les fgets.Sera sûrement l'utiliser !! Merci! – Dmitri

7

scanf ne consomme pas la nouvelle ligne et est donc un ennemi naturel de fgets. Ne les mettez pas ensemble sans un bon hack. Ces deux options fonctionnera:

// 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

Génial !! Merci beaucoup! – Dmitri

+0

De même, en utilisant 'scanf ("% d% * c ", & a)' devrait fonctionner. Le terme '% * c' provoque la lecture de' scanf' dans un caractère (le saut de ligne) mais l'astérisque provoque la suppression de la valeur. Cela fera 'scanf' manger la nouvelle ligne sans nécessiter un appel de fonction séparé. – bta

+0

Vous présentez les deux options comme si elles avaient le même pied, mais 'scanf' est tellement difficile à utiliser qu'il est préférable de ne pas l'utiliser entièrement (voir le lien FAQ de comp.lang.c). Allez-y avec l'option 2. – 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 ne consommera pas \ n il sera pris par l'obtient qui suit la scanf. vider le flux d'entrée après scanf comme ça.

#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

fflush (stdin) et fflush (NULL), dans certaines librairies C, vont vider stdout et stderr, mais ceci est complètement importable! –

0

vous devriez faire de cette façon.

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

pour lire l'entrée de scanf après la lecture.

0

Il suffit d'utiliser 2 gets() Fonctions

Lorsque vous souhaitez utiliser gets() après une fonction scanf(), vous assurez-vous que vous utilisez 2 des gets() et pour le cas ci-dessus écrivez votre code comme:

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; 
} 

Pour l'explication ([email protected]);

+0

bienvenue à SO! S'il vous plaît rappelez-vous que l'anglais n'est pas la première langue de tout le monde ici, alors essayez de poster des réponses qui sont grammaticalement correctes, plutôt que d'utiliser «u» pour «vous» - qui ne fonctionnera pas avec Google Translate! –

0

scanf("%d", &a); ne peut pas lire le retour, car %d n'accepte qu'un nombre entier décimal. Donc vous ajoutez un \n au début du suivant scanf pour ignorer le dernier \n à l'intérieur du tampon.

Ensuite, scanf("\n%s", b); peut maintenant lire la chaîne sans problème, mais scanf s'arrête de lire lorsque trouver un espace blanc. Par conséquent, remplacez %s par %[^\n].Cela signifie: « lire everthing mais \n »

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

Veuillez ajouter une explication du code. – coatless

+0

Explication ajoutée @Coatless –

0

La fonction scanf supprime automatiquement les espaces avant d'essayer d'analyser les choses autres que les caractères. %c, %n, %[] sont des exceptions qui ne suppriment pas les espaces de début.

gets lit le retour à la ligne précédent scanf. Prendre le saut de ligne en utilisant getchar();

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

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