Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1291 connectés 

  FORUM HardWare.fr
  Programmation
  C

  Tableau dynamique de caractères

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Tableau dynamique de caractères

n°1479689
exhortae
Membre du Cartel des Médecins
Posté le 22-11-2006 à 07:54:36  profilanswer
 

Bonjour,  
 
voilà je commence à toucher un petit peu aux pointeurs, et j'ai un petit problème avec le programme suivant. Il est censé permettre la saisie d'une liste de nom, les trier puis les afficher par ordre alphabétque.
 
Le soucis c'est que lors de la saisie (juste après que je rentre le nombre de nom à saisir) et bien le gets me saute la saisie d'un nom
 
au lieu d'afficher
 
Entrez le nom a saisir :  
 
 
il me fait
 
Entrez le nom a saisir :  
Entrez le nom a saisir :  
 
 
et donc au lancement de la boucle je perds la saisie d'un nom. Je sais pas si j'ai été assez clair.
 
voilà le programme, si quelqu'un pouvait me filer un ptit coup de main pour trouver ce qui ne vas pas
 
Merci
 

Code :
  1. #include <stdio.h>
  2. #include <conio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. int main (void)
  6. {
  7. char **noms;
  8. char tempo[20];
  9. int nombre_noms, i, j;
  10. clrscr();
  11. printf("Entrez le nombre de noms a saisir : " );
  12. scanf("%d", &nombre_noms);
  13. noms = (char**) malloc(nombre_noms * sizeof(char*));
  14. /* Saisie + Allocation mémoire */
  15. for (i = 0; i < nombre_noms; i++)
  16. {
  17.  printf("\nEntrez le nom a saisir : " );
  18.  gets(tempo);
  19.         noms[i] = (char*) malloc(strlen(tempo) + 1);
  20.  strcpy(noms[i], strupr(tempo));
  21. }
  22. /* Tri des elements du tableau */
  23. for (i = 0; i < nombre_noms - 1; i++)
  24.  for (j = i + 1; j < nombre_noms; j++)
  25.   if (strcmp(noms[i], noms[j]) > 0)
  26.   {
  27.    strcpy(tempo, noms[i]);
  28.    strcpy(noms[i], noms[j]);
  29.    strcpy(noms[j], tempo);
  30.  }
  31. /* Affichage des elements du tableau */
  32. for (i = 0; i < nombre_noms; i++)
  33.  printf("\n%s", noms[i]);
  34. getch();
  35. return 0;
  36. }

mood
Publicité
Posté le 22-11-2006 à 07:54:36  profilanswer
 

n°1479695
Trap D
Posté le 22-11-2006 à 08:13:14  profilanswer
 

Tu cumules deux problèmes :
- L'utilisation de scanf qui est TRES difficile mais faisable.
- L'utilisation de gets qui est déconseillée puisque gets est un bug (pas de test sur la longueur de la chaine saisie), il faut utiliser fgets(tempo, sizeof tempo, stdin).
Ton problème vient du fait que scanf laisse dans le buffer de saisie le '\n', et donc que la première chose lue par le gets est ce '\n', tu dois vider le buffer de saisie par un while ((c = fgetc(stdin)) != '\n') ;
   
 

n°1479696
Emmanuel D​elahaye
C is a sharp tool
Posté le 22-11-2006 à 08:13:27  profilanswer
 

exhortae a écrit :

voilà je commence à toucher un petit peu aux pointeurs, et j'ai un petit problème avec le programme suivant. Il est censé permettre la saisie d'une liste de nom, les trier puis les afficher par ordre alphabétque.

 

Le soucis c'est que lors de la saisie (juste après que je rentre le nombre de nom à saisir) et bien le gets me saute la saisie d'un nom


Il ne faut pas utiliser gets(). Les saisies en C demandent de l'attention.

 

Je recommande une utilisation exclusive et maitrisée de fgets().

 

http://mapage.noos.fr/emdel/notes.htm#saisie
http://mapage.noos.fr/emdel/notes.htm#fichiers

 

Ton code commenté et corrigé. Bien lire les commentaires (-ed-) et poser des questions si nécessaire.

Code :
  1. #include <stdio.h>
  2. /* -ed-
  3. #include <conio.h>
  4. non standard et probablement inutile pour le probleme a resoudre
  5. */
  6. #include <stdlib.h>
  7. #include <string.h>
  8. /* fonction de nettoyage a appeler apres un fgets */
  9. static void fclean (char *s, FILE * fp)
  10. {
  11.    /* search the end of line marker */
  12.    char *p = strchr (s, '\n');
  13.    if (p != NULL)
  14.    {
  15.       /* found : shoot it */
  16.       *p = 0;
  17.    }
  18.    else
  19.    {
  20.       int c;
  21.       /* not found : purge the pending characters in the incoming stream */
  22.       while ((c = fgetc (fp)) != '\n' && c != EOF)
  23.       {
  24.       }
  25.    }
  26. }
  27. int main (void)
  28. {
  29.    /* -ed-
  30.       char **noms;
  31.       int nombre_noms, i, j;
  32.       Je conseille de reduire la porte des objets et fonctions au strict necessaire
  33.       size_t est le bon type pour les tailles et les indices croissants
  34.     */
  35.    size_t nombre_noms;
  36. /* -ed-
  37. clrscr();
  38. non standard et probablement inutile pour le probleme a resoudre
  39. */
  40.    printf ("Entrez le nombre de noms a saisir : " );
  41.    /* -ed-
  42.       scanf ("%d", &nombre_noms);
  43.       Un usage incorrect de scanf() entraine des comportements instables du
  44.       programme, comme ceux constates. L'usage correct de scanf() est assez difficile.
  45.       Je recommande un usage maitrise et exclusif de fgets().
  46.     */
  47.    {
  48.       char s[8];
  49.       fgets (s, sizeof s, stdin);
  50.       fclean (s, stdin);
  51.       /* -ed- simpliste, mais suffisant pour le moment */
  52.       nombre_noms = (size_t) strtol (s, NULL, 10);
  53.    }
  54. /* -ed-
  55.    noms = (char **) malloc (nombre_noms * sizeof (char *));
  56.    Correct, mais inutilement complexe.
  57.    Par contre, il manque l'essentiel. malloc() peut echouer.
  58. */
  59.    {
  60.       char **noms = malloc (nombre_noms * sizeof *noms);
  61.       if (noms != NULL)
  62.       {
  63.          /* Saisie + Allocation mémoire */
  64.          {
  65.             size_t i;
  66.             for (i = 0; i < nombre_noms; i++)
  67.             {
  68.                char tempo[20];
  69.                printf ("\nEntrez le nom a saisir : " );
  70.                /* -ed-
  71.                   gets (tempo);
  72.                   cette fonction est dangereuse. Il n'est pas possible de limiter
  73.                   le nombre de caracteres entres. Un debordement memoire est
  74.                   toujours possible.
  75.                   fgets() resout ce probleme.
  76.                 */
  77.                fgets (tempo, sizeof tempo, stdin);
  78.                fclean (tempo, stdin);
  79.                /* -ed
  80.                   noms[i] = (char *) malloc (strlen (tempo) + 1);
  81.                 */
  82.                noms[i] = malloc (strlen (tempo) + 1);
  83.                /* -ed- attention strupr() n'est pas standard */
  84.                strcpy (noms[i], strupr (tempo));
  85.             }
  86.          }
  87.          /* Tri des elements du tableau */
  88.          {
  89.             size_t i;
  90.             /* -ed- je recommande l'usage systematique des { }
  91.                avec les structures de code
  92.              */
  93.             for (i = 0; i < nombre_noms - 1; i++)
  94.             {
  95.                size_t j;
  96.                for (j = i + 1; j < nombre_noms; j++)
  97.                {
  98.                   /* -ed- attention, malloc() a pu echouer.
  99.                      Il peut y avoir des pointeurs NULL
  100.                    */
  101.                   if (noms[i] != NULL && noms[j] != NULL)
  102.                   {
  103.                      if (strcmp (noms[i], noms[j]) > 0)
  104.                      {
  105.                         char tempo[20];
  106.                         strcpy (tempo, noms[i]);
  107.                         strcpy (noms[i], noms[j]);
  108.                         strcpy (noms[j], tempo);
  109.                      }
  110.                   }
  111.                }
  112.             }
  113.          }
  114.          /* Affichage des elements du tableau */
  115.          {
  116.             size_t i;
  117.             for (i = 0; i < nombre_noms; i++)
  118.                if (noms[i] != NULL)
  119.                {
  120.                   printf ("\n%s", noms[i]);
  121.                }
  122.          }
  123. /* -ed-
  124. getch();
  125. non standard et probablement inutile pour le probleme a resoudre
  126. */
  127. /* -ed- ce qui a ete alloue doit etre libere */
  128.          {
  129.             size_t i;
  130.             for (i = 0; i < nombre_noms; i++)
  131.             {
  132.                free (noms[i]), noms[i] = NULL;
  133.             }
  134.          }
  135.          free (noms), noms = NULL;
  136.       }
  137.    }
  138.    return 0;
  139. }


Le fonctionnement est maintenant conforme :


Entrez le nombre de noms a saisir : 4

 

Entrez le nom a saisir : ljksd lkjsd

 

Entrez le nom a saisir : jkdfi ds

 

Entrez le nom a saisir : unazlmdj kclkds

 

Entrez le nom a saisir : sdf ryuihdf

 

JKDFI DS
LJKSD LKJSD
SDF RYUIHDF
UNAZLMDJ KCLKDS
Press ENTER to continue.


Mais le tri est améliorable. En effet, on a un tableau de pointeurs. Il suffit donc d'échanger les pointeurs au lieu des chaines, ce sera bien plus rapide.

 

Enfin, le code, tel qu'il est présenté maintenant grâce à la réduction massive de la portée des variables, peut être découpé facilement en fonctions, ce qui le rendra nettement plus clair, en introduisant un nouveau niveau d'abstraction.

 
Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. /* fonction de nettoyage a appeler apres un fgets */
  5. static void fclean (char *s, FILE * fp)
  6. {
  7.    /* search the end of line marker */
  8.    char *p = strchr (s, '\n');
  9.    if (p != NULL)
  10.    {
  11.       /* found : shoot it */
  12.       *p = 0;
  13.    }
  14.    else
  15.    {
  16.       int c;
  17.       /* not found : purge the pending characters in the incoming stream */
  18.       while ((c = fgetc (fp)) != '\n' && c != EOF)
  19.       {
  20.       }
  21.    }
  22. }
  23. static void trier (char **noms, size_t nombre_noms)
  24. {
  25.    size_t i;
  26.    for (i = 0; i < nombre_noms - 1; i++)
  27.    {
  28.       size_t j;
  29.       for (j = i + 1; j < nombre_noms; j++)
  30.       {
  31.          if (noms[i] != NULL && noms[j] != NULL)
  32.          {
  33.             if (strcmp (noms[i], noms[j]) > 0)
  34.             {
  35.                char *tempo = noms[i];
  36.                noms[i] = noms[j];
  37.                noms[j] = tempo;
  38.             }
  39.          }
  40.       }
  41.    }
  42. }
  43. static void afficher (char **noms, size_t nombre_noms)
  44. {
  45.    size_t i;
  46.    for (i = 0; i < nombre_noms; i++)
  47.       if (noms[i] != NULL)
  48.       {
  49.          printf ("\n%s", noms[i]);
  50.       }
  51. }
  52. static void liberer (char **noms, size_t nombre_noms)
  53. {
  54.    size_t i;
  55.    for (i = 0; i < nombre_noms; i++)
  56.    {
  57.       free (noms[i]), noms[i] = NULL;
  58.    }
  59.    free (noms), noms = NULL;
  60. }
  61. int main (void)
  62. {
  63.    size_t nombre_noms;
  64.    printf ("Entrez le nombre de noms a saisir : " );
  65.    {
  66.       char s[8];
  67.       fgets (s, sizeof s, stdin);
  68.       fclean (s, stdin);
  69.       /* -ed- simpliste, mais suffisant pour le moment */
  70.       nombre_noms = (size_t) strtol (s, NULL, 10);
  71.    }
  72.    {
  73.       char **noms = malloc (nombre_noms * sizeof *noms);
  74.       if (noms != NULL)
  75.       {
  76.          /* Saisie + Allocation mémoire */
  77.          {
  78.             size_t i;
  79.             for (i = 0; i < nombre_noms; i++)
  80.             {
  81.                char tempo[20];
  82.                printf ("Entrez le nom a saisir : " );
  83.                fflush (stdout);
  84.                fgets (tempo, sizeof tempo, stdin);
  85.                fclean (tempo, stdin);
  86.                noms[i] = malloc (strlen (tempo) + 1);
  87.                /* -ed- attention strupr() n'est pas standard */
  88.                strcpy (noms[i], strupr (tempo));
  89.             }
  90.          }
  91.          /* Tri des elements du tableau */
  92.          trier (noms, nombre_noms);
  93.          /* Affichage des elements du tableau */
  94.          afficher (noms, nombre_noms);
  95.          /* liberation du tableau */
  96.          liberer (noms, nombre_noms), noms = NULL;
  97.       }
  98.    }
  99.    return 0;
  100. }


On pourrait aller plus loin dans l'abstraction, mais pour le moment, ça devrait suffire.

 

Pose des questions si tu ne comprends pas.

Message cité 1 fois
Message édité par Emmanuel Delahaye le 22-11-2006 à 09:15:51

---------------
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/
n°1480271
exhortae
Membre du Cartel des Médecins
Posté le 22-11-2006 à 20:51:27  profilanswer
 

Trap D a écrit :

Tu cumules deux problèmes :
- L'utilisation de scanf qui est TRES difficile mais faisable.
- L'utilisation de gets qui est déconseillée puisque gets est un bug (pas de test sur la longueur de la chaine saisie), il faut utiliser fgets(tempo, sizeof tempo, stdin).
Ton problème vient du fait que scanf laisse dans le buffer de saisie le '\n', et donc que la première chose lue par le gets est ce '\n', tu dois vider le buffer de saisie par un while ((c = fgetc(stdin)) != '\n') ;


 
Merci

n°1480274
exhortae
Membre du Cartel des Médecins
Posté le 22-11-2006 à 20:53:09  profilanswer
 

Emmanuel Delahaye a écrit :

On pourrait aller plus loin dans l'abstraction, mais pour le moment, ça devrait suffire.
 
Pose des questions si tu ne comprends pas.


 
Vraiment un grand merci à toi d'avoir pris autant de temps pour me répondre,
 
je potasse ça à tête reposée et je reviens ;)
 
 
encore une fois merci :)

n°1481041
exhortae
Membre du Cartel des Médecins
Posté le 23-11-2006 à 23:01:21  profilanswer
 

Me revoilà :)
 
voilà j'ai lu, et essayer d'appliquer (en partie pour commencer), tes conseils.
 
je n'ai pas suivi toutes le recommandations parceque j'aimerais y aller progressivement, voilà j'ai réecri le programme une première fois, si tu pouvais d'abord me dire si c'est correct (par si c'est correct j'entends si il n'y a pas d'erreur, pas si certaines chose sont manquantes ;)). Ensuite j'aimerais te poser dessus quelques questions si tu veux bien.
 
Merci
 

Code :
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. int main (void)
  5. {
  6. size_t nombre_noms;
  7. printf ("Entrez le nombre de noms a saisir : " );
  8. {
  9.  char s[8];
  10.  fgets (s, sizeof s, stdin);
  11.  nombre_noms = (size_t) strtol (s, NULL, 10);
  12. }
  13. {
  14.  char **noms = malloc (nombre_noms * sizeof *noms);
  15.  if (noms != NULL)
  16.  {
  17.   {
  18.    size_t i;
  19.    printf ("\n\n" );
  20.    for (i = 0; i < nombre_noms; i++)
  21.    {
  22.     char tempo[20];
  23.     printf("Entrez le nom a saisir : " );
  24.     fgets (tempo, sizeof tempo, stdin);
  25.     noms[i] = malloc (strlen (tempo + 1));
  26.     strcpy (noms[i], strupr(tempo));
  27.    }
  28.    printf ("\n\n" );
  29.   }
  30.   /* TRI */
  31.   {
  32.    size_t i;
  33.    for (i = 0; i < nombre_noms - 1; i++)
  34.    {
  35.     size_t j;
  36.     for (j = i + 1; j < nombre_noms; j++)
  37.     {
  38.      if (strcmp (noms[j], noms[i]) < 0)
  39.      {
  40.       char tempo[20];
  41.       strcpy (tempo, noms[i]);
  42.       strcpy (noms[i], noms[j]);
  43.       strcpy (noms[j], tempo);
  44.      }
  45.     }
  46.    }
  47.   }
  48.   /* AFFICHAGE */
  49.   {
  50.    size_t i;
  51.    for (i = 0; i < nombre_noms; i++)
  52.     printf("%s", noms[i]);
  53.   }
  54.  }
  55. }
  56.     return 0;
  57. }

Message cité 1 fois
Message édité par exhortae le 23-11-2006 à 23:03:32
n°1481064
Emmanuel D​elahaye
C is a sharp tool
Posté le 23-11-2006 à 23:47:47  profilanswer
 

exhortae a écrit :

je n'ai pas suivi toutes le recommandations parceque j'aimerais y aller progressivement, voilà j'ai réecri le programme une première fois, si tu pouvais d'abord me dire si c'est correct (par si c'est correct j'entends si il n'y a pas d'erreur, pas si certaines chose sont manquantes ;)).  


 
Le fonctionnement est correct, mais la mémoire n'est pas libérée. Si je passe ton code au détecteur de mensonges :  


Usage xxx[ /T][ /E][ /O][ <options application>]
FRMWRK.DBG_SYSALLOC=1
SYSALLOC Overload (85 rec)
SYSALLOC Successful initialization: 85 records available
Entrez le nombre de noms a saisir : 4
 
 
Entrez le nom a saisir : azert
Entrez le nom a saisir : qsdfg
Entrez le nom a saisir : wxcvb
Entrez le nom a saisir : tyuio
 
 
AZERT
QSDFG
TYUIO
WXCVB
SYSALLOC min=4294967295 max=4294967295 delta=0
SYSALLOC Err: Not-matched list:
SYSALLOC Bloc 003D24E8 (16 bytes) malloc'ed at line 23 of 'main.c' not freed
SYSALLOC Bloc 003D2478 (5 bytes) malloc'ed at line 38 of 'main.c' not freed
SYSALLOC Bloc 003D2468 (5 bytes) malloc'ed at line 38 of 'main.c' not freed
SYSALLOC Bloc 003D2500 (5 bytes) malloc'ed at line 38 of 'main.c' not freed
SYSALLOC Bloc 003D2510 (5 bytes) malloc'ed at line 38 of 'main.c' not freed
SYSALLOC Released Memory
FRMWRK.Termine
 
Press ENTER to continue.


Il avoue n'avoir pas libérer la mémoire...

Citation :

Ensuite j'aimerais te poser dessus quelques questions si tu veux bien.


OK.


---------------
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/
n°1481361
exhortae
Membre du Cartel des Médecins
Posté le 24-11-2006 à 15:18:33  profilanswer
 

Bonjour,
 
alors j'ai d'abord une question sur les fonctions d'entrée en c.
 
Voilà je vais commencer à utiliser fgets à la place de scanf.  
Si j'ai bien compris après un fgets il faut utiliser ta fontion fclean (pour vider le flux stdin ??), et c'est la où j'ai un problème, j'ai pas très bien saisie le principe de ta fonction fclean.
 
La fonction prends comme paramètre la chaine que j'ai récupérer avec fgets, et le flux (stdin dans mon cas), Mais l'autre paramètre (FILE * fp) j'ai pas saisi ce que c'est.
 
2) toujours dans la fonction fclean,
 

Code :
  1. char *p = strchr (s, '\n');


 
est-ce que ça veut dire je recherche la sous chaine \n dans la chaine s, et je l'affecte à p le cas échéant???
 
3) dans  

Code :
  1. if (p != NULL)
  2. {
  3.    *p = 0;
  4. }
  5. else
  6. {
  7.    int c;
  8.    while ((c = fgetc (fp)) != '\n' && c!= EOF)
  9. }


la première condition signifie si dans la chaine s  il y a le caractère '\n', *p = 0
 
mais concrètement ça veut dire quoi *p = 0;
 
et ce qu'il y a dans le else pour être honnête j'ai rien compris :)
 
Merci
 
 
PS : pendant que j'y suis , tu connaitrais un editeur, compilateur exécuteur pour le c sous windows.
Un truc avec une interface à peu près potable (pas comme turbo c 2.x et son interface rébarbative sur un lcd)

Message cité 1 fois
Message édité par exhortae le 24-11-2006 à 15:22:01
n°1481376
Emmanuel D​elahaye
C is a sharp tool
Posté le 24-11-2006 à 15:33:29  profilanswer
 

exhortae a écrit :

Voilà je vais commencer à utiliser fgets à la place de scanf.


Bonne idée.

Citation :

Si j'ai bien compris après un fgets il faut utiliser ta fontion fclean (pour vider le flux stdin ??),


entre autres...

Citation :

et c'est la où j'ai un problème, j'ai pas très bien saisie le principe de ta fonction fclean.


Attention, j'ai mis 10 à mettre au point cet algorithme :

 

"Chercher  le '\n. Si il est présent, l'éliminer, sinon lire les caractères non lus sans les stocker."

 

Puissant, non ?

 

Pour les détails d'implémentation, je suggère que tu lises la doc des fonctions. (livre de C, man, help, F1, google...)

 
Citation :

la première condition signifie si dans la chaine s  il y a le caractère '\n', *p = 0


Yo !

Citation :

mais concrètement ça veut dire quoi *p = 0;


A ton avis ? Vraiment aucune idée ?

 

EDIT: je voudrais pas dire, mais mon code était commenté. Tu ne comprends pas l'anglais ? Pas d'informatique sans savoir lire l'anglais.

 
Citation :

tu connaitrais un editeur, compilateur exécuteur pour le c sous windows.


Je recommande Code::Blocks http://www.codeblocks.org/

Message cité 1 fois
Message édité par Emmanuel Delahaye le 24-11-2006 à 15:59:32

---------------
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/
n°1481768
exhortae
Membre du Cartel des Médecins
Posté le 25-11-2006 à 20:27:58  profilanswer
 

Emmanuel Delahaye a écrit :

je voudrais pas dire, mais mon code était commenté. Tu ne comprends pas l'anglais ? Pas d'informatique sans savoir lire l'anglais.
 


 
Je me débrouille plutôt bien en anglais, c'est juste qu'avec les pointeurs, j'ai du mal, mais là c'est bon, j'ai saisie la fonction et je suis capable de la refaire sans l'avoir apprise.
 
sinon voilà j'ai essayé d'appliquer tes conseils en faisant un ptit programme qui conjuge certains verbes du premier groupe, par contre j'ai du mal au niveau du main(), lorsque j'utilise une procédure qui devrait me permettre de tronquer mon verbe. c'est la procédure tronquer qui recoit comme paramètre une chaine de caractère et renvoie la chaine de caractère tronquée, y doit y avoir un soucis de pointeur :/
 
voilà le code
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. static void fclean(char *s, FILE *fp)
  5. {
  6. char *p = strchr (s, '\n');
  7. if (p != NULL)
  8. {
  9.  *p = 0;
  10. }
  11. else
  12. {
  13.  int c;
  14.  while ((c = fgetc(fp)) != '\n' && c != EOF)
  15.  {
  16.  }
  17. }
  18. }
  19. int verification_groupe_1 (char *verbe)
  20. {
  21. size_t longueur_verbe;
  22. int groupe_1;
  23. longueur_verbe = strlen (verbe);
  24. if (verbe[longueur_verbe - 1] == 'r' || verbe[longueur_verbe - 1] == 'R')
  25. {
  26.  if (verbe[longueur_verbe - 2] == 'e' || verbe[longueur_verbe - 2] == 'E')
  27.  {
  28.   return 1;
  29.  }
  30. }
  31. else
  32. {
  33.  return 0;
  34. }
  35. }
  36. static void conjugaison (char *verbe)
  37. {
  38. printf ("\n\nJe %se\n", verbe);
  39. printf ("Tu %se\n", verbe);
  40. printf ("Il, Elle, on %se\n", verbe);
  41. printf ("Nous %sons\n", verbe);
  42. printf ("Vous %sez\n", verbe);
  43. printf ("Ils, Elles %sent\n", verbe);
  44. }
  45. static void tronquer (char *verbe, char **verbe_tronque)
  46. {
  47. verbe[strlen (verbe) - 2] = '\0';
  48. strcpy (*verbe_tronque, verbe);
  49. }
  50. int main (void)
  51. {
  52. char verbe[20];
  53. printf ("Entrez un verbe : " );
  54. fgets (verbe, sizeof verbe, stdin);
  55. fclean (verbe, stdin);
  56. {
  57.  int groupe_1;
  58.  groupe_1 = verification_groupe_1 (verbe);
  59.  if (groupe_1 == 1)
  60.  {
  61.      tronquer (verbe, &verbe);
  62.   conjugaison (verbe);
  63.  }
  64.  else
  65.  {
  66.   printf ("\nLe verbe n'est pas un verbe du 1er groupe\n" );
  67.  }
  68. }
  69. return 0;
  70. }


mood
Publicité
Posté le 25-11-2006 à 20:27:58  profilanswer
 

n°1481770
exhortae
Membre du Cartel des Médecins
Posté le 25-11-2006 à 20:50:39  profilanswer
 

Après recherche plus poussée et différents essais, j'ai remplacer mon main () par ça, et là ça marche, par contre je me demande si c'est correct.
 

Code :
  1. int main (void)
  2. {
  3. char verbe[20];
  4. char *p;
  5. p = verbe;
  6. printf ("Entrez un verbe : " );
  7. fgets (verbe, sizeof verbe, stdin);
  8. fclean (verbe, stdin);
  9. {
  10.  int groupe_1;
  11.  groupe_1 = verification_groupe_1 (verbe);
  12.  if (groupe_1 == 1)
  13.  {
  14.      tronquer (verbe, &p);
  15.   conjugaison (p);
  16.  }
  17.  else
  18.  {
  19.   printf ("\nLe verbe n'est pas un verbe du 1er groupe\n" );
  20.  }
  21. }
  22. return 0;

n°1481808
Emmanuel D​elahaye
C is a sharp tool
Posté le 26-11-2006 à 01:32:57  profilanswer
 

exhortae a écrit :


Code :
  1. char verbe[20];
  2.     char *p;
  3.     p = verbe;
  4. static void tronquer (char *verbe, char **verbe_tronque)
  5. {
  6. verbe[strlen (verbe) - 2] = '\0';
  7. strcpy (*verbe_tronque, verbe);
  8. }



Interdit. Tu n'a pas le droit d'utiliser strcpy() sur le le même tableau. Pour ça, il faut utiliser memmove(). (Lire la doc de ces deux fonctions pour les détails).

 

Je ne vois pas pourquoi tu passes l'adresse du pointeur. Tu ne le modifie pas. C'est l'objet pointé que tu modifies. Tu peux donc écrire (le strcpy() reste faux):

Code :
  1. static void tronquer (char *verbe, char *verbe_tronque)
  2. {
  3. verbe[strlen (verbe) - 2] = '\0';
  4. strcpy (verbe_tronque, verbe);
  5. }


Enfin, un 'tronquage' ne nécessite pas de recopie. Tu peux donc simplifier comme ceci :

Code :
  1. static void tronquer (char *verbe)
  2. {
  3. verbe[strlen (verbe) - 2] = '\0';
  4. }


Il faudrait prendre cependant quelques précautions comme :

Code :
  1. static void tronquer (char *mot)
  2. {
  3.    if (mot != 0)
  4.    {
  5.       size_t const len = strlen (verbe);
  6.       if (len >= 2)
  7.       {
  8.          verbe[len - 2] = '\0';
  9.       }
  10.    }
  11. }


Je pense que si une phase de conception avait été réalisée, on aurait écrit le bon code directement...

 

D'ailleurs ça s'applique à l'ensemble du programme dont le codage me parait bien compliqué, malgré un main() prometteur, il faut le souligner... J'aimerais bien voir le document de conception...


Message édité par Emmanuel Delahaye le 26-11-2006 à 01:38:01

---------------
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/
n°1483978
exhortae
Membre du Cartel des Médecins
Posté le 29-11-2006 à 22:46:38  profilanswer
 

Je met en suspend ce sujet vu que je viens de tomber sur un cours qui explique les pointeurs de zéro (j'ai pas mal de difficultés avec). le temps de l'étudier et je reviens au travail précédent ;)


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  Tableau dynamique de caractères

 

Sujets relatifs
fonction qui renvoie les 4 derniers caractères en vc++ ?[Résolu]Affichage d'un tableau
[PERL] Nom de Variable Dynamique[EXCEL] Eliminer les doublons dans un tableau
Trier un tableau sous excel horizontalement avec VBA(résolu)inserer un tableau dans un forum...
afficher des caracteres accentués dans une fenetre MS-DOSDébordement de tableau invisible !!!
Tableau ou liste linéaire chaînée?JDBC, déclaration dynamique des requête SQL ?
Plus de sujets relatifs à : Tableau dynamique de caractères


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR