[C] Le programme ne s'arrête pas à scanf

18 !!! Messages postés 34 Date d'inscription   Statut Membre Dernière intervention   -  
mamiemando Messages postés 33766 Date d'inscription   Statut Modérateur Dernière intervention   -
Bonjour, je me casse les dents sur un problème qui est sans doute stupide mais qui me met en rogne !!!
voila le code :
int main()
{
    char A, B, C;
    printf("Saisir 1 caractere.\n");
    scanf("%c",&A);
    printf("Saisir 2 caractere.\n");
    scanf("%c",&B);
    printf("Saisir 3 caractere.\n");
    scanf("%c",&C);
    printf("blablabla");
    fflush(stdin);
    getchar();
    return 0;
}



Alors voilà, impossible de saisir correctement les caractères.
ça donne ça en gros :
saisir 1
<je saisi>
saisir2
saisir3
<jen saisi un>
blablabla

c'est pas normal et ça m'énerve ^^'
Si il y a une bonne âme qui passe par la...
Bonne soirée tout le monde.

5 réponses

Hiro
 
Et c'est censé faire quoi, normalement ? :)
0
18 !!! Messages postés 34 Date d'inscription   Statut Membre Dernière intervention   4
 
bin c'est pas vraiment le problème.
Je ne peux pas saisir 3 caractères à la suite.
jai oublié de préciser que si j'enleve printblablabla, tout s'execute normalement.
++
0
mamiemando Messages postés 33766 Date d'inscription   Statut Modérateur Dernière intervention   7 878
 
Il faut scanner un chaîne de trois caractères, non ?
#include <stdio.h>
#include <string.h>

int main(){
  char buffer[255];
  do{
    printf("saisir une chaine de 3 caractères : \n");
    scanf("%s",&buffer);
  }while(strlen(buffer)!=3);
   ...
   return 0;
}
0
ghiz Messages postés 39 Date d'inscription   Statut Membre Dernière intervention   18
 
salut 18,
j'ai déjà rencontré ce problème et je l'avais résolu en ajoutant la fonction fflush(0);
avant le scanf que le compilateur n'accède pas.
bon courage
0
columboweb Messages postés 4 Date d'inscription   Statut Membre Dernière intervention   1
 
Essaye d'enlever les sauts de lignes et exécute.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
mamiemando Messages postés 33766 Date d'inscription   Statut Modérateur Dernière intervention   7 878
 
Une version c++ :

#include <iostream>

int main(){
    char a,b,c;
    std::cout << "Saisir caractere." << std::endl;
    std::cin >> a;
    std::cout << "Saisir caractere." << std::endl;
    std::cin >> b;
    std::cout << "Saisir caractere." << std::endl;
    std::cin >> c;
    std::cout << a << ',' << b << ',' << c << std::endl;
    return 0;
}

Truc suprenant, en C, un fflush ne semble pas réinitialiser correctement le buffer associé à stdin. Du coup celui ci contient deux caractères (le caractère et le retour à la ligne). Du coup, le second caractère lu (fflush ou pas) contient ce retour chariot et donc on se décale. Une combine malhonnête consiste à lire ce caractère dans un caractère bidon (ici x) mais il y a sans doute mieux.

#include <stdio.h>

int main(){
    char a, b, c, x;

    printf("Saisir caractere.\n");
    scanf("%c", &a);
    scanf("%c", &x);

    printf("Saisir caractere.\n");
    scanf("%c", &b);
    scanf("%c", &x);

    printf("Saisir caractere.\n");
    scanf("%c", &c);
    scanf("%c", &x);

    printf("%c, %c, %c\n", a, b, c);
    return 0;
}
0
Arya Dröttningu Messages postés 581 Date d'inscription   Statut Membre Dernière intervention   157
 
Salut,
Il me semble (souvenirs souvenirs......) qu'il faut faire :
scanf("%c%*c", &a);

Le %*c servant justement pour le retour chariot
0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
Bonjour,

L'erreur vient du retour chariot qui traine dans le buffer après la première validation du scanf("%c").
Du coup, il faut vider le buffer.
Pour cela, il n'y a pas mille façon, il faut mettre : getchar();
Ou plus proprement se créer une fonction avec while getchar()...

Donc, si tu mets un getchar() après chacun de tes scanf(), ça fonctionnera très bien ;-))).

De plus, à la place de ton fflush(stdin); il faut mettre fflush(stdout) car tu souhaites vider le buffer écran pour forcer l'affichage. D'ailleurs fflush(stdin) ne doit jamais être utilisé car non standard.

Et enfin, laisse un dernier getchar() avant le return 0; comme tu as fait pour éviter que la fenêtre se referme.

Cdlt,
0
mamiemando Messages postés 33766 Date d'inscription   Statut Modérateur Dernière intervention   7 878
 
Hello fiddy,

En fait désolée d'avoir "déterré" ce sujet mais quelqu'un avait répondu et sa solution comportait quelques petites erreurs. Donc pour remettre le truc au carré j'ai proposé une solution à peu près carrée.

Donc, si tu mets un getchar() après chacun de tes scanf(), ça fonctionnera très bien ;-))).

Ça revient au même que de faire un scanf bidon :s Je trouve ça pas super élégant. Cf en C++ c'est un peu plus classe au niveau du design, ça me surprend qu'on ait pas la même chose en C.

Et enfin, laisse un dernier getchar() avant le return 0; comme tu as fait pour éviter que la fenêtre se referme.

Ça c'est une problématique de windowsien si je peux me permettre... Ou plus exactement d'une personne qui lance un programme non pas depuis un terminal mais depuis par exemple un explorateur de fichiers.

Typiquement le getchar() final "énervera" toute personne susceptible de lancer le programme depuis une ligne de commande (ou au travers d'une chaîne de processus genre pipe & co). Mais bon... ce sont des problématique de linuxiens :p
0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
Salut mamiemando,

En fait désolée d'avoir "déterré" ce sujet mais quelqu'un avait répondu et sa solution comportait quelques petites erreurs. Donc pour remettre le truc au carré j'ai proposé une solution à peu près carrée.
Pas de problème, ça sert à ça un forum après tout ;-))).

Ça revient au même que de faire un scanf bidon :s Je trouve ça pas super élégant.
Certes. Mais cela t'oblige à déclarer une variable, ou alors il faut utiliser %*c. En plus si je dis d'utiliser getchar(), c'est car non seulement c'est plus performant que scanf (qui est lourd en mémoire) mais surtout car la version correcte est :
int c;
while ( (c=getchar()) != '\n' && c != EOF);

C'est ce que j'entendais par while getchar.
Pour ma part, je crée une fonction statique comprenant cette routine et je récris mes fonctions de lecture clavier en me servant de cette fonction, entre autre.

Ou plus exactement d'une personne qui lance un programme non pas depuis un terminal mais depuis par exemple un explorateur de fichiers.

Je plussoie. Mais bon, je me suis résigné à le dire ^^. Je préfère conseiller de mettre le getchar(); voir même carrément le system("pause") (cela évite d'expliquer de mettre deux getchar() dans certains cas), que d'expliquer que la fenêtre va se fermer et qu'il faut le lancer en ligne de commande. Je pense que tu me comprendras ;-))).

Cordialement,
0
abdelmounaime Messages postés 9 Date d'inscription   Statut Membre Dernière intervention   1
 
je vous propose une solution ca marche super b1.
essaye ce code:
#include <stdio.h>
#include <conio.h>
int main()
{
    char A,B,C;
    printf("Saisir 1 caractere.\n");
    scanf("%c",&A);
    printf("Saisir 2 caractere.\n");
    fflush(stdin);
    getchar();
    scanf("%c",&B);
    printf("Saisir 3 caractere.\n");
    scanf("%c",&C);
    printf("blablabla");
    fflush(stdin);
    getchar();
    return 0;
}
0