[C] permettre à l’utilisateur de modifier une chaîne de caractères

permettre à l’utilisateur de modifier une chaîne de caractères [C] - C - Programmation

Marsh Posté le 04-12-2022 à 22:37:00    

Bonjour,
Je suis en train d'apprendre la programmation en C et j'ai essayé de faire l'exercice ci-dessous (voir la consigne de du formateur) et j'aimerais avoir des retours svp :)
 
Voici la consigne de notre formateur concernant l'exercice à faire à la maison :

Citation :


1) A l’aide du "squelette" de la fonction "main" fournit, définissez l’en-tête et le corps de la (ou des) fonction(s) permettant à l’utilisateur du programme de modifier une chaîne de caractères originale (ici ch1) avec les fonctionnalités suivantes :
 
- toutes les apparitions au sein de la chaîne originale, d’un premier caractère entré au clavier par l’utilisateur devront être éliminées ;
 
- toutes les apparitions au sein de la chaîne originale d’un deuxième caractère entré au clavier par l’utilisateur devront être remplacées par un troisième caractère, lui aussi saisi au clavier par l’utilisateur.
 
Vous avez la garantie que l’utilisateur saisira toujours 3 caractères différents.
 
Insérez également les appels de vos fonctions et les variables nécessaires au sein de la fonction "main".
 
 
 
Exemple :
 
Chaîne originale saisie : « CAractere »
1er caractère saisi : ‘e’
2ème caractère saisi : ‘a’
3ème caractère saisi : ‘u’
Chaîne originale modifiée : « CAructr »
 
ATTENTION : Pour cet exercice, la seule fonction de la librairie C que vous pouvez utiliser est la fonction strlen.
 
Commentez votre programme si nécessaire.
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define N 128
  4. int main(int argc, char *argv[])
  5. {
  6.   char ch1 [N];
  7.    printf(« Entrez la chaine originale contenant maximum %d caracteres :\n\n », N - 1);
  8.    gets(ch1);
  9.   system("PAUSE" );
  10.   return 0;
  11. }




 
Attention, je dois utiliser gets() et donc je n'ai pas besoin d'utiliser fgets() à sa place pour cet exercice, même si cela aurait été plus pertinent.
 
 
Voici ce que je suis parvenu à faire :
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h> //inclure la bibliothèque contant la fonction stren()
  4. #define N 30
  5. int remove(char *); //on déclare la varibale qui permettra de modifier la chaine originale
  6. int main(int argc, char *argv[])
  7. {
  8.   char ch1 [N];
  9.    int nbremove=0; //initialiser la var qui permet de compter au-moins l'un des 3 caractères entrés par l'utilisateur
  10.    printf("Entrez la chaine originale contenant maximum %d caracteres :\n\n, N - 1" );
  11.    gets(ch1); //on ne doit pas utiliser fgets() pour cette exercice pour saisir la chaine
  12.    if (nbremove) {
  13.      printf("Voici le nombre de caractères entrés : %d\n",nbremove); // on vérifie si c'est bien 3
  14.      printf("Chaîne originale modifiée :\n" );
  15.      puts(ch1); //afficher à la console
  16.    } else printf ("Veuillez indiquez 3 caractères\n" );
  17.   system("PAUSE" );
  18.   return 0;
  19. }
  20. //fonction 1 pour supprimer le premier caractère demandé par l'utilisateur
  21. int remove (char * x) {
  22. int cpt=0, indlect=0, indecrit=0, lg=strlen(x);
  23. char xrecherchee[4]; //je dois chercher dans la chaine saisis par l'utilisateur + je laisse une place pour le '\0'
  24. printf ("Entrez les 3 caractères \n" );
  25. gets(xrecherchee); //xrecherchee contiendra ces 3 caractères
  26. while (indlect <= lg ) //trouve les caractères qui sont identiques à la première entrée par l'utilisateur
  27. {
  28.  if (
  29.  x[indlect] == xrecherchee[1] ) {
  30.   cpt++;
  31.   indlect=indlect +1; //indlect += 1;
  32.  }
  33.  else //sinon je recopie simplement les mêmes caractères dans x
  34.  {
  35.   x[indecrit]=x[indlect];
  36.   indlect++;
  37.   indecrit++;
  38.  }
  39. }
  40. //afficher le résultat de la première fonction
  41. while (x[indlect])
  42. {
  43. x[indecrit]=x[indlect];
  44. indlect++;
  45. indecrit++;
  46. }
  47. x[indecrit]='\0';
  48. return cpt;
  49. }//fin de la 1re fonction
  50. //fonction 2
  51. int remplace (char * x2)
  52. {
  53. int cpt = 0;
  54. char xrecherchee[2];
  55. char x3=xremplacement[3];
  56. while (indlect <= lg))
  57. {
  58.  if ( x[indlect] == xrecherchee[2] )
  59.  {
  60.   x[indlect] = sremplacement[3];
  61.   x = x + 1;
  62.   cpt++;
  63.  }
  64.  else
  65.   x++;
  66. }
  67. return cpt;
  68. }


 
 
Merci de m'avoir lu

Reply

Marsh Posté le 04-12-2022 à 22:37:00   

Reply

Marsh Posté le 05-12-2022 à 14:48:26    

Dommage qu'il soit obligé d'utiliser gets, cette fonction ne devrait plus être utilisée.
 
http://pwet.fr/man/linux/fonctions_bibliotheques/gets/
 

Citation :


BOGUES
N'utilisez jamais gets(). Comme il est impossible de savoir à l'avance combien de caractères seront lus par gets(), et comme celui-ci écrira tous les caractères lus, même s'ils débordent du tampon, cette fonction est extrèmement dangereuse à utiliser. On a déjà utilisé ce dysfonctionnement pour créer des trous de sécurité. UTILISEZ TOUJOURS fgets() À LA PLACE DE gets().


 
 
Par ailleurs, le début de ton programme comporte des erreurs :  
 - ligne 12 : ton printf est faux. Le N-1 doit être à l'extérieur des guillemets.
 - ligne 15 : ton test va forcément échouter car nbremove est initialisée à 0 en ligne 11 et n'est pas modifiée ensuite.
 
 
Pour tes 2 fonctions remove et remplace :
 - elles ne sont pas appelées pour le moment, elles ne vont donc rien faire.
 - pour la fonction remove :  
    * ligne 32 à 34, tu demandes de saisir 3 caractères, mais ton tableau fait une taille 4. Attention au débordement de tableau comme expliqué précédemment, et cela suppose donc qu'on saisit 3 caractères sans espace, et seulement 3. Le premier est donc l'élément 0, le second 1, et le 3eme 2, tandisque que le dernier ( 4eme) est le caractère fin de ligne du tableau.
    * ensuite dans ta boucle, tu compares avec xrecherchee[1] qui est le second caractère, or, c'est le premier qu'il te faut. ( ligne 39 )
    * ton test ligne 36 va aller trop loin. En effet, lg contient la longeur de ta chaine. Par exemple "abcdef" , lg vaut 6. Par contre, les index de ton tableau vont de 0 à 5.  
    * ligne 47 , tu peux écrire x[indecrit++] = x[indlect++]; le ++ sera fait après chaque instruction.
    * enfin, en faisant comme ça, tu ne vas pas décaler le caractère fin de ligne ( '\0' ). Il te manque quelque chose du genre x[indecrit] = '\0' à la fin de la boucle.
    * la boucle entre 59 et 62 me fait dire que tu n'as peut être pas tout compris. Tu répètes des choses que tu as déjà faites auparavant. De plus indlect n'étant pas réinitialisé à 0, il commence à la fin de lg, donc il ne se passera rien ici en fait.
 - pour la fonction remplace,
    * idem remove, c'est xrecherchee[1]et xrecherchee[2] et non 2 et 3.
    * tu ne lis pas sur l'entrée standard tes caractères, donc les tests suivants ne fonctionneront pas. Alors que tu as lu les 3 caractères avec ta fonction précédente, mais tu ne te sers que tu premier. Je pense que tu devrais lire les 3 caractères en dehors des fonctions, et ensuite tu passes en paramètres des 2 fonctions les caractères voulus. Par exemple :  
        -> int recherche( char*x , char remove ) { ... }
        -> int remplace ( char*x , char from, char to ) { ... }
    * ligne 78 , comme expliqué précédemment tu declares xrecherchee mais c'est un tableau non initialisé. Je suppose que tu penses que vu que ca a le même nom, ca a été modifié dans la fonction précédente ( xrecherchee[4] ) mais pas du tout, ce sont 2 variables différentes , quand bien même elles sont le même nom, elles sont déclarées localement à chaque fonction, leur scope (portée , existence ) se limite à la fonction.
    * la suite est forcément fausse, même si la logique ne l'est pas complètement ( lg n'est pas non plus initialisée, c'est aussi une autre variable que celle dans "remove" )
    * ligne 79, tu mets dans x3 quelque chose qui n'existe pas ( xremplacement n existe pas ) et tu ne te sers pas de x3. Ligne fausse et inutile
   
 
Bon courage ;)
 

Reply

Marsh Posté le 06-12-2022 à 20:50:31    

Merci pour tes précieux commentaires :) Oui je suis d'accord sur le fait qu'il soit dommage d'utiliser gets()....
 
Puis-je avoit un retour sir ce code svp ? :
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h> // inclure la bibliothèque contenant la fonction strlen()
  4. #define N 30
  5. #define R 3
  6. int supprime(char *);
  7. int remplace(char *);
  8. int main(int argc, char *argv[])
  9. {
  10.    char ch1 [N];
  11.    printf("Entrez la chaine originale contenant maximum %d caracteres :\n\n, N - 1" );
  12.    gets(ch1);
  13.    char ch1 [N];
  14.    printf("Entrez 3 caracteres :\n\n, N - 1" );
  15.    gets(work);
  16.         int n;
  17.         if ((n=supprime(ch1, work[0])) != 0)
  18.                 printf("Chaine réduite\n", ch1, n);
  19.         else
  20.                 printf("Chaine non réduite \n", ch1);
  21.         if ((n=remplace(ch1, work[1], work[2])) != 0)
  22.                 printf("Chaine remplacée, ch1, n);
  23.         else
  24.                 printf("Chaine non remplacée\n", ch1);
  25.        
  26.   system("PAUSE" );
  27.   return 0;
  28. }
  29. int supprime(char* s, char lettre) {
  30.         int lg=strlen(s);
  31.         int indLect=0;
  32.         int indEcrit=0;
  33.         while (indLect < lg) {
  34.                 if (s[indLect] != lettre) {
  35.                         s[indEcrit]=s[indLect];
  36.                         indEcrit++;
  37.                 }
  38.                 indLect++;
  39.         }
  40.         s[indEcrit]='\0';
  41.         return lg - strlen(s);
  42. }
  43. int remplace(char* s, char x, char y) {
  44.         int lg=strlen(s);
  45.         int n=0;
  46.         int i=0;
  47.         while (i < lg) {
  48.                 if (s[i] == x) {
  49.                         s[i]=y;
  50.                         n++;
  51.                 }
  52.                 i++;
  53.         }
  54.         return n;

Reply

Marsh Posté le 07-12-2022 à 16:26:08    

Bonjour,
 
Quelques petites erreurs, voici la version corrigée pour que ça "compile" :  
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h> // inclure la bibliothèque contenant la fonction strlen()
  4. #define N 30
  5. #define R 3
  6. int supprime(char *, char);
  7. int remplace(char *, char , char);
  8. int main(int argc, char *argv[])
  9. {
  10.    char ch1 [N];
  11.    printf("Entrez la chaine originale contenant maximum %d caracteres :\n\n", N - 1 );
  12.    gets(ch1);
  13.    char work [N];
  14.    printf("Entrez 3 caracteres :\n\n", N - 1 );
  15.    gets(work);
  16.         int n;
  17.         if ((n=supprime(ch1, work[0])) != 0)
  18.                 printf("Chaine réduite %s %d\n", ch1, n);
  19.         else
  20.                 printf("Chaine non réduite %s\n", ch1);
  21.         if ((n=remplace(ch1, work[1], work[2])) != 0)
  22.                 printf("Chaine remplacée, %s %d\n", ch1, n);
  23.         else
  24.                 printf("Chaine non remplacée%s \n", ch1);
  25.      
  26.   system("PAUSE" );
  27.   return 0;
  28. }
  29. int supprime(char* s, char lettre) {
  30.         int lg=strlen(s);
  31.         int indLect=0;
  32.         int indEcrit=0;
  33.         while (indLect < lg) {
  34.                 if (s[indLect] != lettre) {
  35.                         s[indEcrit]=s[indLect];
  36.                         indEcrit++;
  37.                 }
  38.                 indLect++;
  39.         }
  40.         s[indEcrit]='\0';
  41.         return lg - strlen(s);
  42. }
  43. int remplace(char* s, char x, char y) {
  44.         int lg=strlen(s);
  45.         int n=0;
  46.         int i=0;
  47.         while (i < lg) {
  48.                 if (s[i] == x) {
  49.                         s[i]=y;
  50.                         n++;
  51.                 }
  52.                 i++;
  53.         }
  54.         return n;
  55. }


 
en vrac :  
 - ligne 8 et 9 : prototypes de fonction incorrects
 - ligne 18 : mauvaise variable déclarée 2 fois, il manque work par contre.
 - ligne 15 : guillemet au mauvais endroit
 - ligne 24 26 29 31 : il faut mettre des %s %d pour que les variables s'affichent, de plus guillemet manqueant ligne 29
 - après ligne 69 : manque accolade fermante
 
 
Tu peux tester ton code ici : https://www.onlinegdb.com/
 
tu verras qu'il y a plein de warnings ;)

Reply

Marsh Posté le 08-12-2022 à 01:32:48    

Merci ! :)

Reply

Sujets relatifs:

Leave a Replay

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