web-dev-qa-db-fra.com

Simple C scanf ne fonctionne pas?

Si j'essaie quelque chose comme:

int anint;
char achar;

printf("\nEnter any integer:");
scanf("%d", &anint);
printf("\nEnter any character:");
scanf("%c", &achar);
printf("\nHello\n");
printf("\nThe integer entered is %d\n", anint);
printf("\nThe char entered is %c\n", achar);

Cela permet de saisir un entier, puis de sauter la seconde scanf complètement, ce qui est vraiment étrange, car lorsque je permute les deux (le char scanf en premier), cela fonctionne bien. Qu'est-ce qui pourrait mal se passer?

20
John

Lors de la lecture d'une entrée à l'aide de scanf, l'entrée est lue après avoir appuyé sur la touche Retour, mais la nouvelle ligne générée par la clé de retour n'est pas utilisée par scanf, ce qui signifie que la prochaine fois que vous lirez une char à partir de l'entrée standard, une nouvelle ligne sera prête lis.

Une façon d'éviter consiste à utiliser fgets pour lire l'entrée en tant que chaîne, puis extrayez ce que vous voulez en utilisant sscanf comme:

char line[MAX];

printf("\nEnter any integer:");
if( fgets(line,MAX,stdin) && sscanf(line,"%d", &anint)!=1 ) 
   anint=0;

printf("\nEnter any character:");
if( fgets(line,MAX,stdin) && sscanf(line,"%c", &achar)!=1 ) 
   achar=0;

Une autre façon de consommer la nouvelle ligne serait de scanf("%c%*c",&anint);. Le %*c lira la nouvelle ligne à partir de la mémoire tampon et l’éliminera.

Vous voudrez peut-être lire ceci:

C FAQ: Pourquoi tout le monde dit de ne pas utiliser scanf?

25
codaddict

Les autres réponses sont correctes - %c ne saute pas les blancs. Le moyen le plus simple de le faire est de placer des espaces avant le %c:

scanf(" %c", &achar);

(Tout espace dans la chaîne de format fera que scanf consommera tous les espaces consécutifs).

14
caf

Il ne saute pas la deuxième scanf(); la seconde scanf() lit la nouvelle ligne laissée par la première scanf(). La plupart des codes de format ignorent les espaces; le format %c ne saute pas les espaces.

5
Jonathan Leffler

Essayez également _flushall () après chaque appel à printf. . Fondamentalement, par défaut, les buffers C++ de MS produisent un flux de sortie et le vidage entraîne le vidage du flux de sortie.

0
rkellerm

appeler getchar() avant scanf purgera également le saut de ligne stocké. Plus léger mais plus situationnel

char input_1;
char input_2;
getchar();
scanf("%c", &input_1);
getchar();
scanf("%c", &input_2);

effacera les sauts de ligne, plus utile dans les lignes de code consécutives où vous savez qu'il ne s'agit que d'une valeur en file d'attente et non d'une chaîne

0
Dale Diaz