Probléme language C

Probléme language C - C - Programmation

Marsh Posté le 25-02-2011 à 01:12:28    

Bonsoir,
Je voudrais juste un peu d'aide dans un exercice en langage C.
Cette exercice consiste a compter les espaces, les tabulations et les fins de lignes.
Mon code fonctionne mais partiellement, je n'arrive pas a faire en sorte qu'il affiche tout en une ligne.
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main()
  4. {
  5.     int espace=0;
  6.     int tabulation=0;
  7.     int finDeLigne=0;
  8.     while((c=getchar()) != EOF) {
  9.         if(c==' ')
  10.           espace++;
  11.         if(c=='\t')
  12.           tabulation++;
  13.         if(c=='\n')
  14.           finDeLigne++;
  15.         printf("Il y a %d espaces,%d tabulation et %d fin de ligne\n",espace,tabulation,finDeLigne);
  16.     }
  17. return 0;
  18. }


 
Merci.


Message édité par bill g@te le 25-02-2011 à 01:14:18
Reply

Marsh Posté le 25-02-2011 à 01:12:28   

Reply

Marsh Posté le 25-02-2011 à 01:18:25    

Est-ce que tu as vu que tu as mis le printf dans la boucle while?

Reply

Marsh Posté le 25-02-2011 à 01:28:46    

Oui mr simon, mais si je met pas le printf dans la boucle, le texte ne sera jamais afficher car le programme ne rencontre jamais la fin de fichier " EOF" non ?

Reply

Marsh Posté le 25-02-2011 à 14:49:03    

J'avais lu un peu vite, je croyais que tu utilisais un fichier ...
 
Je ne sais pas quel est le comportement que tu souhaites, mais si tu mets le printf dans le if qui teste la fin de ligne, ca devrait etre plus lisible.
 
Sinon, il faut que tu regardes du cote de atexit.

Reply

Marsh Posté le 25-02-2011 à 15:23:15    

D'accord, merci du conseil.
Mais en soit mon programme fonctionne mais le problème, c'est lorsque je rentre au clavier par exemple : " Salut[espace][entrée]"
Le entrée n'est comptabiliser que dans un second temps.  
"Il y a 1 espaces,0 tabulation et 0 fin de ligne
Il y a 1 espace,0 tabulation et 1 fin de ligne"
 
Alors que l'idéal serait : Il y a 1 espaces,0 tabulation et 1 fin de ligne.
 

Reply

Marsh Posté le 25-02-2011 à 15:50:01    

Juste une remarque : il me semble que taper la combinaison "CTRL + D" envoie le caractère EOF.

Reply

Marsh Posté le 26-02-2011 à 23:57:15    

Merci de l'info shaoyin, mais il y a t-il une solution pour " mon probléme " ?
Merci

Reply

Marsh Posté le 27-02-2011 à 01:29:25    

ton problème, c'est que tu affiches ta ligne pour chaque caractère rencontré. Au lieu de traiter directement caractère par caractère, traite des lignes complètes et affiche le détail de la ligne une fois ton traitement terminé


---------------
last.fm
Reply

Marsh Posté le 27-02-2011 à 10:58:50    

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main()
  4. {
  5.   int espace = 0;
  6.   int tabulation = 0;
  7.   int finDeLigne = 0;
  8.   int c; /* Cette déclaration manquait */
  9.   while((c = getchar()) != EOF) {
  10.     if (c == ' ') espace++;
  11.     else if (c == '\t') tabulation++;
  12.     else if (c == '\n') {
  13.       finDeLigne++;
  14.       /* On met le print dans ce bloc si tu veux l'affichage a chaque ligne tapée */
  15.       /* sinon, pour un seul affichage global globale, on met le print après le while */
  16.       printf("Il y a %d espaces, %d tabulation et %d fin de ligne\n", espace, tabulation, finDeLigne);
  17.     }
  18.   }
  19.   return 0;
  20. }


Compilé soux XP avec le compilo Digital Mars, et ça donne bien "Il y a 1 espace, 0 tabulation et 1 fin de ligne" quand je tape en entrée  "Salut[espace][entrée]".  
Mettre le printf a chaque tour de boucle est totalement inutile, vu que stdin est bufferisé, et ne recoit les caractères que ligne à ligne, quand un '\n' a été tapé.
 
Sous Dos, EOF, c'est CTRL+Z.
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 27-02-2011 à 11:12:46    

theshockwave a écrit :

ton problème, c'est que tu affiches ta ligne pour chaque caractère rencontré. Au lieu de traiter directement caractère par caractère, traite des lignes complètes et affiche le détail de la ligne une fois ton traitement terminé

Il traite chaque caractère rencontré dans stdin une fois que stdin contient une ligne complète terminée par un '\n', ce qui est complètement inefficace. stdin n'est pas unbuffered (et il y a de bonnes raisons pour, sauf à vouloir gérer le backspace, etc), et il n'existe pas de méthode générale pour intercepter les appuis claviers, sauf a vouloir écrire du code OS+GUI dépendant.
A+,


Message édité par gilou le 27-02-2011 à 11:13:14

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 27-02-2011 à 11:12:46   

Reply

Marsh Posté le 27-02-2011 à 11:28:32    

Merci theshockwave, j'aurai du y penser ;)
Voici mon code au cas ou qu'il y a des reproches, des conseils,etc...  
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main()
  4. {
  5.     int nbEspaces=0;
  6.     int nbTabulation=0;
  7.     int nbLignes=0;
  8.     int c=0;
  9. while((c=getchar())!= EOF) {
  10.     while((c=getchar()) !='\n')
  11.     {
  12.         if(c==' ')
  13.         nbEspaces++;
  14.         else if(c=='\t')
  15.         nbTabulation++;
  16.         c=0;
  17.     }
  18. nbLignes++;
  19.        printf("Il y a %d espaces,%d tabulation et %d fin de ligne\n",nbEspaces,nbTabulation,nbLignes);
  20. }
  21.     return 0;
  22. }


 
Edit : Effectivement Gilou cela fonctionne, merci des remarques ;)

Message cité 1 fois
Message édité par bill g@te le 27-02-2011 à 11:36:32
Reply

Marsh Posté le 27-02-2011 à 11:49:17    

Wrong code. :o

Reply

Marsh Posté le 27-02-2011 à 15:49:14    

bill g@te a écrit :

Edit : Effectivement Gilou cela fonctionne, merci des remarques ;)

 

Si j'avais eu à le faire partant de 0, j'aurais grosso modo procédé ainsi:

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdbool.h>
  4. void print_stat(int stat[3], bool end) {
  5.   char c = (end?'.':'>');
  6.   printf("SP[%d] TB[%d] LN[%d]%c", stat[0], stat[1], stat[2], c);
  7.   fflush(stdout);
  8. }
  9. int main()
  10. {
  11.   int stat[3] = {0, 0, 0}; /* spaces, tabs, new lines */
  12.   bool end = false;
  13.   print_stat(stat, end);
  14.   while(!end) {
  15.     char c;
  16.     switch (c = getchar()) {
  17.     case ' ': ++stat[0];
  18.       break;
  19.     case '\t': ++stat[1];
  20.       break;
  21.     case '\n': ++stat[2];
  22.       print_stat(stat, end);
  23.       break;
  24.     case EOF:
  25.       end = true;
  26.       print_stat(stat, end);
  27.       break;
  28.     }
  29.   }
  30.   return 0;
  31. }


A+,


Message édité par gilou le 27-02-2011 à 15:51:55

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 28-02-2011 à 20:33:37    

Ok merci du code !
Pourrais-je savoir en quoi j'ai faux au moin,Christaline ?

Reply

Marsh Posté le 28-02-2011 à 21:21:52    

Bien sur, tu appelles deux fois getchar(). :jap:

Reply

Marsh Posté le 28-02-2011 à 23:46:07    

bill g@te a écrit :

Ok merci du code !


Tiens, le même genre de code, mais qui n'imprime la ligne qu'à la fin, et qui permet de stopper aussi avec CTRL+C [Sous windows, comme un un CTRL+C vide le buffer, on perd la ligne en cours, (sinon, il faut écrire du code non portable avec <windows.h> et les fonctions de l'API windows), et j'ai fait en sorte que ce soit pareil sous linux, même si sous linux, il y aurait moyen, avec du code un peu plus complexe, de s’arrêter sur un CTRL+C sans perdre la ligne en cours, je pense]  

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdbool.h>
  4. #include <signal.h>
  5. static bool ended = false;
  6. void user_exit(int sig) {
  7.   ended = true;
  8.   signal(SIGINT, SIG_DFL);
  9. }
  10. int main()
  11. {
  12.   int stat[3] = {0, 0, 0}; /* spaces, tabs, new lines */
  13.   /* on installe une interception de CTRL+C pour imprimer en quittant */
  14.   signal(SIGINT, user_exit);
  15.   while(!ended) {
  16.     switch (getchar()) {
  17.     case ' ': ++stat[0];
  18.       break;
  19.     case '\t': ++stat[1];
  20.       break;
  21.     case '\n': ++stat[2];
  22.       break;
  23.     case EOF:
  24.       ended = true;
  25.       break;
  26.     }
  27.   }
  28.   printf("\nSP[%d] TB[%d] LN[%d].\n", stat[0], stat[1], stat[2]);
  29.   return 0;
  30. }


A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed