les boucles et affichage de motif ...

les boucles et affichage de motif ... - C - Programmation

Marsh Posté le 17-02-2008 à 20:36:16    

Bonjour j'essaie de faire un programme qui affiche un nombre d'étoile déterminé par l'utilisateur par exemple (1):
*
**
***
****
***
**
*
mais je n'arrive à afficher que cala :
*
**
***
****
mon problème et que je n'arrive pas à faire diminuer le nombre d'étoile de 1 voici le code que j'ai qui fonctionne mais qui affiche les étoiles comme dans l'exemple (2) :

Code :
  1. #include <stdio.h>
  2. main()
  3. {
  4.       int i=1,j,nb;
  5.   printf("triangle\nnombre de ligne : " );
  6.   scanf("%d",&nb); //demande le nombre de lignes
  7.   printf("\n" ); //retour a la ligne
  8.   for(i=1;i<=nb;i++) //boucle qui permet le retour a la ligne  
  9.       {
  10.          for(j=1;j<=i;j++) //boucle qui permet le nombre afficher '*' en fonction de la boucle du i  
  11.          {
  12.              printf("*" );           
  13.                         }
  14.              printf("\n" );   // retour a la ligne pour la mise en forme
  15.            }
  16.    printf("\n\adessin termine \a\n\n" ); // signale la fin du dessin
  17.  
  18.   system("PAUSE" ); //pour pouvoir regarder le résultat final
  19. }


 
j'ai pensé à faire un if .. else ca me donne quelque chose comme cela :

Code :
  1. #include <stdio.h>
  2. main()
  3. {
  4.       int i=1,j,nb;
  5.   printf("triangle\nnombre de ligne : " );
  6.   scanf("%d",&nb); //demande le nombre de ligne
  7.   printf("\n" ); //retour a la ligne
  8.   for(i=1;i<=nb;i++) //boucle qui permet le retour a la ligne  
  9.       {
  10.          if (i!=(nb/2)){for(j=1;j<=i;j++) // i différent du nombre de ligne divisé par 2 alors j'affiche 1/2du dessin complet
  11.          {
  12.              printf("*" ); }           
  13.                        
  14.          else  // quand la condition n'est plus vérifié je diminue de 1 ce qui doit permettre  de faire la derniere du dessin
  15.          for(j=1;j<=i;j--)
  16.          {
  17.              printf("*" );           
  18.                        
  19.              printf("\n" );}   }
  20.            }
  21.    printf("\n\adessin termine \a\n\n" );
  22.  
  23.   system("PAUSE" );
  24. }


et bien sûr le code n'est pas compilable. [syntaxe error before else --> je ne trouve pas l'erreur :( ]
 
Est-ce que vous pouvez m'aider à régler ce problème je suis débutant dans ce langage C et j'ai essayé de faire avec les tables mais c'est aussi délicat pour moi que de faire avec cette manière.
 
P.S. : je travaille avec Dev-C je sais pas si c'est vraiment important. J'aimerai aussi savoir si ce programme pourra être aussi utilisé sous Ubuntu?

Reply

Marsh Posté le 17-02-2008 à 20:36:16   

Reply

Marsh Posté le 17-02-2008 à 21:32:19    

Code :
  1. main()


 
C'est :
int main(void)
ou  
int main(int argc, char **arv)
 

Code :
  1. scanf("%d",&nb);


Non.  
scanf() est une fonction avancée, et son utilisation ne se fait pas à la légère. Elle est malheureusement encore et toujours enseignée sans discernement.
Preuve : entre une chaîne de caractères à la place d'un nombre, et admire ton programme qui meurt dans d'atroces souffrances.
 
Dans un cas comme celui-ci, il vaut mieux utiliser fgets() pour lire la chaîne de caractères, puis la convertir à l'aide, par exemple, de strtol().
 

Code :
  1. for(i=1;i<=nb;i++) //boucle qui permet le retour a la ligne  
  2.       {
  3.          if (i!=(nb/2)){for(j=1;j<=i;j++) // i différent du nombre de ligne divisé par 2 alors j'affiche 1/2du dessin complet
  4.          {
  5.              printf("*" ); }           
  6.                        
  7.          else  // quand la condition n'est plus vérifié je diminue de 1 ce qui doit permettre  de faire la derniere du dessin
  8.          for(j=1;j<=i;j--)
  9.          {
  10.              printf("*" );           
  11.                        
  12.              printf("\n" );}   }
  13.            }
  14.    printf("\n\adessin termine \a\n\n" );
  15. }


 
Tu te prends la tête pour rien.
Fais une première boucle qui affiche les étoiles en ordre croissant de taille, puis une seconde qui affiche en ordre décroissant.
 

Citation :

et bien sûr le code n'est pas compilable. [syntaxe error before else --> je ne trouve pas l'erreur :( ]


Normal, il manque une accolade fermante.
Améliore ton indentation : une présentation claire du code, ça permet de détecter ce genre d'erreur rapidement.
En reprenant ton code tel quel, une meilleure indentation donne ceci :

Code :
  1. for(i=1;i<=nb;i++) //boucle qui permet le retour a la ligne  
  2. {
  3.    if (i!=(nb/2))
  4.    {
  5.       for(j=1;j<=i;j++) // i différent du nombre de ligne divisé par 2 alors j'affiche 1/2du dessin complet
  6.       {
  7.          printf("*" );
  8.       }           
  9.                      
  10.    else  // quand la condition n'est plus vérifié je diminue de 1 ce qui doit permettre  de faire la derniere du dessin
  11.       for(j=1;j<=i;j--)
  12.       {
  13.          printf("*" );           
  14.          printf("\n" );
  15.       } 
  16.    }
  17. }
  18.    printf("\n\adessin termine \a\n\n" );
  19. }


Et là on voit clairement qu'il y a un souci avec les accolades.
 

Citation :

Est-ce que vous pouvez m'aider à régler ce problème je suis débutant dans ce langage C et j'ai essayé de faire avec les tables mais c'est aussi délicat pour moi que de faire avec cette manière.


Il y a effectivement un meilleur moyen de parvenir à tes fins, mais pour l'heure il vaut mieux d'abord savoir les programmes que tu rencontres avec ce code-ci.
 

Citation :

P.S. : je travaille avec Dev-C je sais pas si c'est vraiment important. J'aimerai aussi savoir si ce programme pourra être aussi utilisé sous Ubuntu?


S'il est bien écrit et qu'il respecte la norme, tu pourras compiler ton code sur toute plateforme possédant un compilateur normé.
dev-cpp utilise mingw, qui est un port de GNU C sous Windows. Sous Ubuntu, il te suffira de compiler ton code avec gcc (GNU C donc), et ça ira sans problème.... sauf pour le system("PAUSE" ) de la fin, puisque la commande "PAUSE" n'existe pas sous Linux.

Reply

Marsh Posté le 17-02-2008 à 21:52:58    

En cours on a appris a faire un programme de la manière suivante :

Citation :


#include <stdio.h>
main()
{
declaration
+
code
}


aussi j'aimerai savoir a quoi sert  

Citation :

int main(void)
ou  
int main(int argc, char **arv)


 
surtout le void et la signification de : (int argc, char **arv)  
 
 
j'ai aussi essayer de faire une boucle croissante et décroissante à la place du if, else j'ai reussi a afficher quelque chose mais ce n'est pas encore ca voici le code :
 

Code :
  1. #include <stdio.h>
  2. int main(int argc, char **arv) 
  3. {
  4.       int i=1,j,nb,k;
  5.   printf("triangle\nnombre de ligne : " );
  6.   scanf("%d",&nb); //demande le nombre de ligne
  7.   printf("\n" ); //retour a la ligne
  8.  
  9.  
  10.      for(i=1;i<=(nb/2);i++) //boucle qui permet le retour a la ligne + boucle croissante
  11.      {
  12.           for(j=1;j<=i;j++) // i différent du nombre de ligne divisé par 2 alors j'affiche 1/2du dessin complet
  13.           {
  14.              printf("*" );
  15.           }         
  16.           printf("\n" );             
  17.      }
  18.  
  19.      for(i=nb/2;i<=1;i++) //boucle qui permet le retour a la ligne + boucle decroissante
  20.      {
  21.           for(j=1;j<=i;j--) // i différent du nombre de ligne divisé par 2 alors j'affiche 1/2du dessin complet
  22.           {
  23.              printf("*" );
  24.           }         
  25.           printf("\n" );                 
  26.      }
  27.  
  28.  
  29.       printf("\n\adessin termine \a\n\n" );
  30.      
  31.   system("PAUSE" );
  32. }


 
j'ai aussi saisi le probleme du scanf --> boucle infini quand le programme est lancé
est ce que je pourrais savoir en quoi consiste la méthode plus facile et l'expliquer pour que je puisse essayer de la faire.

Reply

Marsh Posté le 17-02-2008 à 22:34:24    

amteurasm a écrit :

En cours on a appris a faire un programme de la manière suivante :

Code :
  1. #include <stdio.h>
  2. main()
  3. {
  4.    declaration
  5.    +
  6.    code
  7. }




C'est une manière de faire complètement obsolète.

 

1 - La norme C99 exige que le type retourné soit explicite
2 - Il est recommandé, depuis C90, d'utiliser les prototypes.

Code :
  1. int main(void)


est une forme correcte. void signifie 'pas de paramètres'.

Code :
  1. int main(int argc, char **arv)


est aussi une forme correcte qui permet la récupération des paramètres passés sur la ligne de commande. Détails dans ton livre de C.

Citation :


j'ai aussi essayer de faire une boucle croissante et décroissante à la place du if, else j'ai reussi a afficher quelque chose mais ce n'est pas encore ca voici le code :


Il manque des choses...


Project   : Forums
Compiler  : GNU GCC Compiler (called directly)
Directory : C:\dev\forums\
--------------------------------------------------------------------------------
Switching to target: default
Compiling: main.c
main.c: In function `main':
main.c:36: warning: implicit declaration of function `system'
main.c:5: warning: unused variable `k'
main.c: At top level:
main.c:3: warning: unused parameter 'argc'
main.c:3: warning: unused parameter 'arv'
main.c: In function `main':
main.c:37: warning: control reaches end of non-void function
main.c:37:2: warning: no newline at end of file
Linking console executable: console.exe
Process terminated with status 0 (0 minutes, 7 seconds)
0 errors, 6 warnings


  • inclure <stdlib.h> pour system()...
  • k n'est pas utilisé : suppression.
  • int argc, char **arv n'est pas utilisé : suppression.
  • comme main() retourne un int : return 0;
  • Tu t'embrouilles avec les ++ et les --. Refléchi mieux à ce que tu dois faire, y compris par écrit, avant de coder...
Citation :


j'ai aussi saisi le probleme du scanf --> boucle infini quand le programme est lancé
est ce que je pourrais savoir en quoi consiste la méthode plus facile et l'expliquer pour que je puisse essayer de la faire.


Le plus simple est de purger les caractères non lus après la lecture :

Code :
  1. scanf ("%d", &nb);           //demande le nombre de ligne
  2.    purge();


avec

Code :
  1. void purge (void)
  2. {
  3.    int c;
  4.    while ((c = getchar()) != '\n' && c != EOF)
  5.    {
  6.    }
  7. }



Message édité par Emmanuel Delahaye le 17-02-2008 à 22:46:52

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 18-02-2008 à 09:36:24    

je dois dire que la je ne comprends pas vraiment le principe de la fonction, j'ai un niveau débutant en C.
J'ai aussi compiler le code d mon message précédent et il fonctionne correctement le problème et que je n'affiche que :
*
**
pour 5 lignes alors que je devrait avoir quelque chose comme ca :
*
**
***
**
*
 
est ce que je pourrais aussi savoir ce que veut dire la condition du while est-ce : tant que le caractère de c différent de retour charriot et c différent de ??? faire quelque chose ici peut etre une boucle infini mais je ne sais pas trop ( j en ne comprend pas le OEF

Reply

Marsh Posté le 18-02-2008 à 09:46:08    

Code :
  1. for(j=1;j<=i;j--)


Essaie d'analyser cette ligne, ce qu'elle va faire.

Reply

Marsh Posté le 18-02-2008 à 10:31:49    

en relisant ce que j'ai écrit j'ai u quelques erreurs :

Code :
  1. for(i=nb/2;i<=1;i++) //boucle qui permet le retour a la ligne + boucle decroissante
  2.       {
  3.            for(j=1;j<=i;j--) // i différent du nombre de ligne divisé par 2 alors j'affiche 1/2du dessin complet
  4.            {
  5.               printf("*" );
  6.            }       
  7.            printf("\n" );               
  8.       }


 
je pense que ca serait mieux comme ca :

Code :
  1. for(i=nb/2;i<=nb;i++) //boucle qui permet le retour a la ligne + boucle decroissante
  2.       {
  3.            for(j=nb/2;j<=1;j--) // i différent du nombre de ligne divisé par 2 alors j'affiche 1/2du dessin complet
  4.            {
  5.               printf("*" );
  6.            }       
  7.            printf("\n" );               
  8.       }


néanmoins même après ces corrections j'ai l'impression que je ne rentre pas dans la boucle pourtant le code me semble correcte et je ne vois pas trop ce qui m'empeche de rentrer dans la boucle

Reply

Marsh Posté le 18-02-2008 à 11:22:24    

Quel que soit le langage, le code ne sert qu'à retranscrire un algorithme de manière intelligible pour la machine.
 
Oublie pour le moment le code, et déroule ton algorithme.
Ce que tu fais dans ta dernière "correction", c'est ça :

POUR CHAQUE i, de nb/2 à nb, FAIRE :
   POUR CHAQUE j, de nb/2 à 1, FAIRE :
      Afficher '*'
   FIN POUR
 
   Afficher un saut de ligne
FIN POUR


 
Ne trouves-tu pas qu'il y a un problème ? [:opus dei]

Reply

Marsh Posté le 18-02-2008 à 11:51:06    

J'ai une boucle croissante pour compléter le nombre de ligne et une autre décroissante pour afficher une étoile de moins à chaque ligne, je ne trouve pas le problème mais y en un puisque ca ne fonctionne pas et comme nb/2>1 et que je fait j-- je ne vois pas le probleme

Reply

Marsh Posté le 18-02-2008 à 11:51:57    

Tu n'as pas l'impression que tu afficheras le même nombre d'étoiles à chaque itération de i ?

Reply

Marsh Posté le 18-02-2008 à 11:51:57   

Reply

Marsh Posté le 18-02-2008 à 12:14:26    

heu non pas trop, comment ca pourrait afficher tout le temps le meme nombre d'étoile etant donné que l'itération qui affiche l'étoile est dans la boucle j-- et que j'affiche en fonction de cette variable.
de plus quand je compile mon code il ne se passe que cela:  
*
**
***  
pour 5 lignes il en manque donc 2 celle de la boucle décroissante ; elle ne s'affiche pas donc je ne vois pas en quoi afficher tout le meme nombre d'étoile empeche l'affichage de celle-ci ...

Reply

Marsh Posté le 18-02-2008 à 13:29:13    

Bah écoute, cette ligne...

Code :
  1. for(j=nb/2;j<=1;j--)


...fait que le nombre d'étoiles sera toujours le même, parce que j est censé varier entre nb/2 et 1, et que cet intervalle ne change jamais quel que soit i.

 

Après, en démarrant de nb/2, j sera toujours >= 1. Donc la condition d'arrêt est vérifiée avant même d'entrer dans la boucle, c'est pour ça qu'il n'affiche rien.


Message édité par Elmoricq le 18-02-2008 à 13:34:37
Reply

Marsh Posté le 18-02-2008 à 13:45:00    

d'accord merci de cette précision est de bien vouloir m'aider, j'ai changé un peu la structure pour y mettre des fonctions : une pour la boucle croissante et une autre pour la décroissante.
 
voici le code  

Code :
  1. #include<stdio.h>
  2. void affichem1(int nb) // fonction pour la boucle croissante
  3. {
  4.   int i,j;
  5.   for(i=1;i<=nb/2;i++) //boucle qui permet le retour a la ligne  
  6.       {
  7.          for(j=1;j<=i;j++) //boucle qui permet le nombre afficher '*' en fonction de la boucle du i  
  8.          {
  9.              printf("*" );           
  10.                         }
  11.              printf("\n" );   // retour a la ligne pour la mise en forme
  12.            }
  13. }
  14. void affichem2(int nb) // fonction pour la boucle décroissante
  15. {
  16.   int i,j;
  17.   for(i=nb/2;i<=nb;i++) //boucle qui permet le retour a la ligne  
  18.       {
  19.          for(j=nb;j!=i;j--) //boucle qui permet le nombre afficher '*' en fonction de la boucle du i  
  20.          {
  21.              printf("*" );           
  22.                         }
  23.              printf("\n" );   // retour a la ligne pour la mise en forme
  24.            }
  25. }
  26. void main(void//programme principal
  27. {
  28.   int nb;   
  29.   printf("triangle\nnombre de ligne : " );
  30.   scanf("%d",&nb); //demande le nombre de lignes
  31.   printf("\n" ); //retour a la ligne
  32.   affichem1(nb);
  33.   affichem2(nb);
  34.   printf("\n\adessin termine \a\n\n" ); // signal la fin du dessin   
  35.   system("PAUSE" ); //pour pouvoir regarder le résultat final
  36. }


est ce que vous avez des conseils à me donner pour optimiser le fonctionnement ?

Reply

Marsh Posté le 18-02-2008 à 13:55:08    

Oui, mais tu ne les as visiblement pas lus, je les répète donc :

  • void main(void) n'est pas un prototype de main() valide.  
  • scanf() n'est pas une fonction qui s'utilise aussi simplement que tu l'as écrit, et mène à de nombreux problèmes. Lis le contenu de ce lien : http://mapage.noos.fr/emdel/notes.htm#saisie , tu y verras notamment un lien vers un cours pour correctement utiliser scanf(), ce qui n'est pas trivial. Utilise plutôt fgets()
  • Il manque stdlib.h pour pouvoir utiliser system().

Reply

Marsh Posté le 18-02-2008 à 19:10:29    

merci beaucoup
Dans le même genre j'aimerai faire un dessin de ce type :
     *
   ***
 *****
   ***      
     *
En me basant sur un dessin que j'ai fait j'ai pu déduire un le positionnement de l'étoile par rapport à la marge donc :
je dois faire une boucle de i=1 a n/2+1
puis afficher n-i-2 espaces
et afficher n - 2*(i+1) etoiles
Aussi existe-t-il une fonction avec laquelle je puisse positionner mon étoile en fonction de variables ?

Reply

Sujets relatifs:

Leave a Replay

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