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

Fermé
18 !!! Messages postés 34 Date d'inscription vendredi 16 janvier 2004 Statut Membre Dernière intervention 20 novembre 2006 - 20 nov. 2006 à 19:35
mamiemando Messages postés 33441 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 19 décembre 2024 - 9 nov. 2010 à 21:06
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

Et c'est censé faire quoi, normalement ? :)
0
18 !!! Messages postés 34 Date d'inscription vendredi 16 janvier 2004 Statut Membre Dernière intervention 20 novembre 2006 4
20 nov. 2006 à 19:42
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 33441 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 19 décembre 2024 7 810
20 nov. 2006 à 19:51
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 lundi 28 août 2006 Statut Membre Dernière intervention 16 août 2008 18
20 nov. 2006 à 22:58
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 jeudi 23 novembre 2006 Statut Membre Dernière intervention 13 janvier 2008 1
23 nov. 2006 à 01:15
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 33441 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 19 décembre 2024 7 810
8 nov. 2010 à 18:45
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 mardi 12 janvier 2010 Statut Membre Dernière intervention 3 janvier 2019 157
8 nov. 2010 à 18:48
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 samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 843
8 nov. 2010 à 20:48
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 33441 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 19 décembre 2024 7 810
9 nov. 2010 à 00:18
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 samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 843
9 nov. 2010 à 00:47
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 vendredi 22 octobre 2010 Statut Membre Dernière intervention 13 décembre 2015 1
9 nov. 2010 à 01:07
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