Tableau dynamique de caractères

Tableau dynamique de caractères - C - Programmation

Marsh Posté le 22-11-2006 à 07:54:36    

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. }

Reply

Marsh Posté le 22-11-2006 à 07:54:36   

Reply

Marsh Posté le 22-11-2006 à 08:13:14    

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') ;
   
 

Reply

Marsh Posté le 22-11-2006 à 08:13:27    

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/
Reply

Marsh Posté le 22-11-2006 à 20:51:27    

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

Reply

Marsh Posté le 22-11-2006 à 20:53:09    

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 :)

Reply

Marsh Posté le 23-11-2006 à 23:01:21    

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
Reply

Marsh Posté le 23-11-2006 à 23:47:47    

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/
Reply

Marsh Posté le 24-11-2006 à 15:18:33    

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
Reply

Marsh Posté le 24-11-2006 à 15:33:29    

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/
Reply

Marsh Posté le 25-11-2006 à 20:27:58    

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. }


Reply

Marsh Posté le 25-11-2006 à 20:27:58   

Reply

Marsh Posté le 25-11-2006 à 20:50:39    

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;

Reply

Marsh Posté le 26-11-2006 à 01:32:57    

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/
Reply

Marsh Posté le 29-11-2006 à 22:46:38    

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 ;)

Reply

Sujets relatifs:

Leave a Replay

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