Problème Progamme pour affichage

mystix5987
Problème Progamme pour affichage

Bonjour à tous, cela fait un bout de temps que je cherche une solution sur le forum dans des sujets déjà traités, mais je n'ai rien trouvé.

J'ai un souci tout bête, mais je ne sais pas le régler : Je pose un entier a égal à 1 au début. Tant que a<5, je demande une lettre et un chiffre. Je sais c'est bête mais en fait c'est la simplification de ce que j'ai dans un autre programme car après j'utilise ces données, et j'en redemande d'autres pour les traiter à nouveau.

J'écris donc en C (normal, on est sur un forum concernant le C), j'utilise Dev-C++ 4.9.9.2.

Voici mon code :

#include <stdio.h>

int main (void)

{  int a,chiffre;
   char lettre1;
     
   a=1;
     
   while (a<5)
   {  
     printf("ligne\n");
     fflush(stdout); 
     scanf("%c*c",&lettre1);
     printf("%c\n",lettre1);
     printf("colonne\n");
     fflush(stdout); 
     scanf("%d",&chiffre);
     printf("%d\n\n",chiffre);
     a++;
  } 
  
system("PAUSE");

}

Pourriez-vous me dire où se trouve mon erreur ? Pour "fflush(stdout);", je l'ai trouvé sur le forum, ça a corrigé un peu le problème mais pas entièrement.

Merci à vous.

jrebillat

Ta façon de récupérer les entrées est bizarre, surtout pour l'entier.
J'ai tendance à séparer la lecture de la ligne entrée d'une part et l'analyse de l'autre, comme ça :

#include <stdio.h>

int main (void)

{  int a,chiffre;
   char lettre1;
   char buf[10];
     
   a=1;
     
   while (a<5)
   { 
     printf("--------------------------\n");
     printf("ligne\n");
     fflush(stdout);
     scanf("%s",buf);
     sscanf(buf, "%c*c",&lettre1);
     printf("%c\n",lettre1);
     printf("colonne\n");
     fflush(stdout);
     scanf("%s",buf);
     sscanf(buf,"%d", &chiffre);
     printf("%d\n",chiffre);
     a++;
  }
}
mystix5987

Problème : je ne comprends pas "buf" ni "sscanf" ni "fflush(stdout)" (car trouvé sur un forum mais pas tout compris)

fredericmazue

Bonjour,

Je réponds aux trois posts d'un coup si vous me le permettez.

Quote:

Bonjour à tous, cela fait un bout de temps que je cherche une solution sur le forum dans des sujets déjà traités, mais je n'ai rien trouvé.

LoL :lol: :lol:
C'est à croire que plus personne ne connaît le C ;)
Bon tu vas trouver ici alors :)

Quote:

Pourriez-vous me dire où se trouve mon erreur ? Pour "fflush(stdout);", je l'ai trouvé sur le forum, ça a corrigé un peu le problème mais pas entièrement.

Quel problème ? Ton code n'est pas faux du point de vue du langage. Si tu dis qu'il y a problème c'est qu'il ne se comporte pas comme tu l'entends, et dans ce cas, c'est une bonne idée de préciser le problème dans la question.
Il n'y a aucune raison que fflush(stdout) règle quoi que ce soit.

Quote:

Ta façon de récupérer les entrées est bizarre, surtout pour l'entier.

Non c'est correct. Ca ne marche pas mais c'est correct ;)

Ah les mystères des entrées/sorties du C...

Bon tout d'abord:
La chaîne de formatage "%c*c" n'a pas de sens.
Le signe * dans une chaîne de formatage est un inhibiteur d'affectation. Concrètement dans le cas présent "%c*c" veut dire: on affecte dans lettre1 puis on affecte pas dans lettre1, ce qui n'a pas de sens, donc.

Voilà où est le problème. Quant tu fais scanf("%c*c",&lettre1); tu lis 1 (j'insiste, un seul) caractère depuis la console. MAIS tu en saisis DEUX. Le caractère lui même et le retour chariot (return) qui reste dans le tampon.
Quand tu repasses sur scanf("%c*c",&lettre1); tu lis toujours 1 caractère mais lequel ? Tu en saisis toujours deux, à savoir une lettre et un retour chariot. Donc dans le tampon d'entrées, il y a maintenant TROIS caractères deux retour chariot et une lettre, à la queue leu leu comme ceci

retour-chariot -- lettre -- retour-chariot

que lit REELLEMENT le scanf alors ? tout simplement le premier retour chariot. et ainsi de suite.

Le code proposé par jrebillat fonctionne car il lit une chaîne totale avec le scanf ce qui a pour effet de dégager le retour chariot final (ainsi en est il des entrées/sorties du C et de leurs contradictions) qui est donc sorti du tampon d'entrée. Puis il convertit la chaîne lue en la valeur voulue avec sscanf (mystix, je te renvoie à la doc de ton compilo ou une doc en ligne sur le C, ca sera expliqué). Toutefois dans le code de jrebillat, la chaîne de formatage "%c*c" n'a pas plus de sens et les fflush sont tout autant inutiles.

Voici le code que tu voulais écrire. le principe consiste à faire tomber le retour chariot de saisie dans une trappe (char dummy)

#include <stdio.h> 


int main (void) 

{  int a,chiffre; 
   char lettre1;
   char dummy;
      
   a=1; 
      
   while (a<5) 
   {  
     printf("ligne\n"); 
     scanf("%c%c",&lettre1, &dummy); 
     printf("%c\n",lettre1); 
     printf("colonne\n"); 
     scanf("%d",&chiffre);
	 scanf("%c",&dummy);
     printf("%d\n\n",chiffre); 
     a++; 
  } 
}

Maintenant ATTENTION.
Le code est correct du point de vue du C et du point de vue du comportement souhaité.
Ca n'en reste pas moins une hérésie de programmation car si l'utilisateur saisit 2 caractères au lieu d'un seul demandé il y a débordement de tampon et comportement abberrant. Donc je crains que toute la copie ne soit à revoir en fait. Mais dans un premier temps pour essayer le reste de ton programme, tu peux partir là-dessus.
Le code proposé par jrebillat est plus sécurisé, mais présente le même problème si un facétieux saisit 10 caractères. Avec le zéro de fin de chaîne ;) ca en fait 11 et on a un bon vieux débordement de tampon des familles dans buf.

jrebillat

:D
Bravo pour la démonstration !
On en apprend tous les jours, je ne connaissais pas le 'truc' du %c*c...

fredericmazue

Merci :)
Tu sais les entrées/sorties du C c'est plein de facéties et autres curiosités. Il y aurait un bouquin à écrire rien que là-dessus.
Moi même je suis bien loin de tout connaître....