Partage
  • Partager sur Facebook
  • Partager sur Twitter

fonction qui supprime un caractère

Sujet résolu
    15 janvier 2020 à 21:12:01

    Bonjour je cherche un moyen de crée une fonction qui supprime un caractère dans une chaine de caractère en paramètre. 

    voici mon code : 

    void del (char mot[], char c);
    
    int main()
    {
        char mot[1000] = "eddy";
        char c = 'y';
        printf("%s", del(mot, c));
        return 0;
    
    }
    
    
    
    void del (char mot[], char c)
    {
    
        int i = 0;
        for (i = 0; mot[i] != '\0'; i++)
        {
            if (mot[i]==c)
            {
                c =""; // Je ne sais pas trop quelle instruction mettre pour que le caractère soit supp de la chaine
            }
        } 
    
    }
    • Partager sur Facebook
    • Partager sur Twitter
      15 janvier 2020 à 22:29:07

      Bonsoir, je ne pense pas que tu peut faire ça avec un tableau constant tu va avoir besoin d'un tableau dynamique et si tu n'a pas envie de t'embêter avec une fonction utilisé une liste chainée mais les listes chainée son un peu compliqué à utiliser si tu est débutant.

      -
      Edité par Proto. 15 janvier 2020 à 22:38:42

      • Partager sur Facebook
      • Partager sur Twitter
        15 janvier 2020 à 22:40:02

        Imagine une fonction qui prend les caractères d'une chaîne et les copie dans une autre chaîne,  sauf si c'est 'y'.

        Ensuite tu regardes ce que ça donne si on utilise le même tableau pour les deux chaînes 

        -
        Edité par michelbillaud 15 janvier 2020 à 22:41:13

        • Partager sur Facebook
        • Partager sur Twitter
          15 janvier 2020 à 23:05:58

          @Proto.:
          Utiliser une liste chaînée? Il faut aimer les problèmes.
          Si tu ajoutais des caractères à la chaîne de départ, il y aurait danger de débordement.
          Mais si tu en enlèves, il n'y a pas de problème.
          @One_Shot:
          Ligne 26;
                      c =""; // Je ne sais pas trop quelle instruction mettre pour que le caractère soit supp de la chaine
          Tu fais une boucle où tu décales les caractères suivants ce caractère d'une position vers la gauche.
          La gauche étant les plus petits indices ...
          -
          do {
           mot[i] = mot[i+1];
           i++;
          } while(mot[i] != '\0');

          -
          Edité par PierrotLeFou 16 janvier 2020 à 3:09:35

          • Partager sur Facebook
          • Partager sur Twitter

          Le Tout est souvent plus grand que la somme de ses parties.

            16 janvier 2020 à 6:45:10

            Indication : le caractère peut apparaître plusieurs fois dans la chaîne.

            Décaler d'une position quand on en trouve un n'est pas une bonne solution.

            (algorithme quadratique au lieu de linéaire, il y avait un bug de ce type bien connu dans le code du serveur web apache, dans le nettoyage des url pour éliminer les  "../".)

            -
            Edité par michelbillaud 16 janvier 2020 à 6:45:34

            • Partager sur Facebook
            • Partager sur Twitter
              16 janvier 2020 à 8:33:15

              C'est moins évident à faire, mais on décale de N positions, on incrémente N de 1 à chaque occurence.
              • Partager sur Facebook
              • Partager sur Twitter

              Le Tout est souvent plus grand que la somme de ses parties.

                16 janvier 2020 à 9:04:44

                michelbillaud a écrit:

                (algorithme quadratique au lieu de linéaire, il y avait un bug de ce type bien connu dans le code du serveur web apache, dans le nettoyage des url pour éliminer les  "../".)

                -
                Edité par michelbillaud il y a environ 1 heure

                En effet, décaler a un cout. Ce qui peut être fait, c'est séparer un algorithme de suppresion, qui va remplacer les caractères à supprimer par un caractère spécial, et une fois qu'on a fini toutes les suppressions, procéder à un seul décalage, avec un curseur d'écriture toujours inférieur ou égal à celui de lecture.



                -
                Edité par Fvirtman 16 janvier 2020 à 9:05:08

                • Partager sur Facebook
                • Partager sur Twitter

                Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

                  16 janvier 2020 à 9:43:18

                  Qu'est ce que vous allez chercher comme complication ...

                  pour chaque caractère c de la chaine source
                    |  si c doit être gardé
                    |      le mettre dans la chaine destination
                  

                  En C, version naïve en style javaesque :

                  void copier_en_eliminant(char elim, char *source, char *destination)
                  {
                       int d = 0;    // indice dans la chaine de destination
                       for(int s = 0; source[s] != '\0' ; s++) {
                            if (elim == source[s]) {
                                 destination[d] = c;
                                 d += 1;
                            }
                       }
                  }
                  

                  Après, si on veut faire le malin, on se la pète avec des pointeurs et des tournures idiomatiques à l'ancienne

                  void copier_en_eliminant(char elim, char *src, char *dst)
                  {
                      char *s = src, *d = dst;
                      while ( (*d = *s++) != '\0' ) { 
                         if (*d != elim) d++;
                      }
                  }
                  

                  qui nécessitent l'achat d'une boite d'aspirine (on copie d'abord le caractère, puis on regarde si il faut le conserver ou pas dans la chaine destination. Ce qui fait que le NUL à été copié).

                  Et pour éliminer sans copier, on confond source et destination.



                  -
                  Edité par michelbillaud 17 janvier 2020 à 8:47:15

                  • Partager sur Facebook
                  • Partager sur Twitter
                    16 janvier 2020 à 12:56:07

                    michelbillaud a écrit:

                    Imagine une fonction qui prend les caractères d'une chaîne et les copie dans une autre chaîne,  sauf si c'est 'y'.

                    Ensuite tu regardes ce que ça donne si on utilise le même tableau pour les deux chaînes 

                    -
                    Edité par michelbillaud il y a environ 14 heures


                    Je vais m'en tenir à cette idée pour l'instant. Ce que les autres racontes m'a l'air compliqué 

                    Merci beaucoup pour toutes vos réponses ! 

                    • Partager sur Facebook
                    • Partager sur Twitter
                      16 janvier 2020 à 13:46:41

                      michelbillaud a écrit:

                      qui nécessitent l'achat d'une boite d'aspirine 

                      Ce n'est plus en vente libre depuis hier mercredi 15 janvier 2020 !

                      • Partager sur Facebook
                      • Partager sur Twitter
                        16 janvier 2020 à 15:25:34

                        J'ai fait ceci sans Aspirine. Je pense que ça marche:
                        -
                        int decale = 0;
                        int i = 0;
                        do {
                         if(a_eliminer(mot[i]))  decale++;
                         mot[i-decale] = mot[i];
                        } while(mot[i++] != '\0');

                        -
                        Edité par PierrotLeFou 16 janvier 2020 à 15:30:55

                        • Partager sur Facebook
                        • Partager sur Twitter

                        Le Tout est souvent plus grand que la somme de ses parties.

                          16 janvier 2020 à 15:51:45

                          Faut pas penser, faut tester.

                          #include <stdio.h>
                          #include <string.h>
                          
                          void eliminer(char a_eliminer, char * mot) {
                          	int decale = 0;
                          	int i = 0;
                          	do {
                          		if(a_eliminer == mot[i])  decale++;
                          		mot[i-decale] = mot[i];
                          	} while(mot[i++] != '\0');
                          }
                          
                          void tester(char * avant, char c, char *apres) {
                          	char copie[100];
                          	printf("test avec \"%s\"\n", avant);
                          	strcpy(copie, avant);
                          	printf("- attendu \"%s\"\n", apres);
                          	eliminer(c, copie);
                          	printf("- obtenu  \"%s\"\n", copie);
                          	if (strcmp(copie, apres) != 0) {
                          		printf("* ERREUR");
                          	}
                          	printf("\n");
                          }
                          
                          int main(int argc, char **argv)
                          {
                          	tester("abc",    'a', "bc");
                          	tester("abcabc", 'a', "bcbc");
                          	return 0;
                          }
                          


                          Résultats :

                          test avec "abc"
                          - attendu "bc"
                          - obtenu  "bc"
                          
                          test avec "abcabc"
                          - attendu "bcbc"
                          - obtenu  "babc"
                          * ERREUR
                          
                          



                          -
                          Edité par michelbillaud 16 janvier 2020 à 15:58:03

                          • Partager sur Facebook
                          • Partager sur Twitter
                            16 janvier 2020 à 18:15:37

                            Peut-être que j'aurais dû prendre des Aspirines après tout ...
                            J'ai placé un 'els'e après le 'if' de la ligne 8 (?)
                            J'ai ajouté les tests:
                            tester("abcabcz", 'z', "abcabc");
                            tester("abccba", 'c', "abba");
                            tester("aaaaaa", 'a', "");
                            Et ça fonctionne.
                            Comment fait-on pour tester la fonction de test?
                            • Partager sur Facebook
                            • Partager sur Twitter

                            Le Tout est souvent plus grand que la somme de ses parties.

                              16 janvier 2020 à 21:37:01

                              REEEE tout le monde j'ai trouvé un truc qui fonctionne à peu près !!!!
                              #include <stdio.h>
                              #include <stdlib.h>
                              
                              void del (char mot[], char c);
                              int main()
                              {
                                  char mot[1000] = "eddy";
                                  char c = 'y';
                                  del(mot, c);
                                  printf("%s", mot);
                                  return 0;
                              
                              }
                              
                              
                              
                              void del (char mot[], char c)
                              {
                              
                                  int i = 0;
                                  for (i = 0; mot[i] != '\0'; i++)
                                  {
                                      if (mot[i]==c)
                                      {
                                          c="";
                                          mot[i] = c; // Je ne sais pas trop quelle instruction mettre pour que le caractère soit supp de la chaine
                                      }
                                  }
                              
                              }
                              • Partager sur Facebook
                              • Partager sur Twitter
                                16 janvier 2020 à 22:15:15

                                Conseil, tu testes d'abord sur plusieurs exemples. Et après tu dis que ca marche.
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  16 janvier 2020 à 23:17:31

                                  One_Shot a écrit:

                                  REEEE tout le monde j'ai trouvé un truc qui fonctionne à peu près !!!!


                                  Alors, ça ne fonctionne pas.
                                  • Partager sur Facebook
                                  • Partager sur Twitter

                                  On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

                                    16 janvier 2020 à 23:30:31

                                    J'ai dit que je "pensais" que mon code foncttionnait.
                                    Je n'ai jamais dit comme One_Shot que mon code foncttionnait "à peu près".
                                    Il a encore dans son code:
                                                mot[i] = c; // Je ne sais pas trop quelle instruction mettre pour que le caractère soit supp de la chaine
                                    Ça fonctionne, ou ça ne fonctionne pas.
                                    J'ai toujours le code de michelbillaud (corrigé) et j'ai ajouté la ligne suivante:
                                    tester("", 'x', "");
                                    et:
                                    tester("abcdef", 'z', "abcdef");

                                    -
                                    Edité par PierrotLeFou 16 janvier 2020 à 23:42:18

                                    • Partager sur Facebook
                                    • Partager sur Twitter

                                    Le Tout est souvent plus grand que la somme de ses parties.

                                      16 janvier 2020 à 23:46:46

                                      edgarjacobs a écrit:

                                      One_Shot a écrit:

                                      REEEE tout le monde j'ai trouvé un truc qui fonctionne à peu près !!!!


                                      Alors, ça ne fonctionne pas.


                                      Ca fonctionne. C'est le résultat que je voulais donc ça fonctionne.
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        17 janvier 2020 à 1:10:30

                                        Ma compilation de ton dernier code donne:
                                        .xx.c: In function 'del':
                                        .xx.c:25:14: warning: assignment to 'char' from 'char *' makes integer from pointer without a cast [-Wint-conversion]
                                        .             c="";                                                                                                      
                                        .              ^                                                                                                         
                                                                                  J'ai mis les  .  pour préserver les espaces. L'exécution donne:                                                                          
                                        edd
                                        C'est ce que tu veux?
                                        • Partager sur Facebook
                                        • Partager sur Twitter

                                        Le Tout est souvent plus grand que la somme de ses parties.

                                          17 janvier 2020 à 7:58:37

                                          Si c'est pour trouver qu'en enlevant la dernière lettre de "eddy" on trouve "edd", il n'y avait pas besoin d'ecrire un programme.

                                          Un programme, ça doit marcher dans tous les cas.

                                          Essaie d'enlever le 'd', pour voir.

                                          Tester, ça ne prouve JAMAIS que ça marche, parce qu'on ne peut pas essayer tous les cas. Par contre, si on propose des cas de test divers et variés, on a plus de chances de remarquer que ça ne marche pas.

                                          Ton test c'était un cas très particulier : une seule occurrence, qui se trouve à la fin. Faut être un peu sérieux, quand on fait les tests.

                                          -
                                          Edité par michelbillaud 17 janvier 2020 à 8:03:32

                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            17 janvier 2020 à 15:30:32

                                            C'est pourquoi j'ai essayé "plusieurs" tests.
                                            J'ai essayé quelques cas limites comme enlever au début, à la fin, quelque chose qui n'est pas là, ou tout enlever.
                                            Mais je ne peux en effet pas "tout" tester.
                                            Même dire qu'il y a des milliards de possibilités est insuffisant.
                                            • Partager sur Facebook
                                            • Partager sur Twitter

                                            Le Tout est souvent plus grand que la somme de ses parties.

                                              17 janvier 2020 à 17:37:20

                                              One_Shot a écrit:

                                              Ca fonctionne. C'est le résultat que je voulais donc ça fonctionne.

                                              ----

                                              Bon, regardons calmement.

                                              1. Déjà quand on compile la fonction del, le compilateur couine

                                              gcc -Wall -o "del." "del..c" (dans le dossier : /mnt/roost/users/mibillau)
                                              del..c: In function ‘del’:
                                              del..c:23:14: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
                                                           c="";
                                                            ^

                                              C'est très mauvais signe. Pour les débutants qui font des choses pas trop sportives normalement, c'est révélateur d'un bug.

                                              Ici : ça demande de mettre l'adresse de la chaine vide dans un char (qui est assimilé à un entier, merci les inventeurs de C).


                                              2. Si on fait tourner, et qu'on se décide à ouvrir les yeux (désolé pour Pierrot, capture d'écran), on risque de voir quelque chose comme ça (ça va dépendre du système, du jeu de caractères etc).



                                              En clair, ça a collé une merde à la place du y. C'est pas ce que j'appellerais "marcher"

                                              3.  Avec
                                                char mot[1000] = "eddddddy";
                                                  char c = 'd';

                                              C'est joli aussi



                                              et on voit que seul le premier 'd' a été traité.

                                              @pierrot, historiquement, c'est Turing qui s'est rendu compte qu'on ne pouvait pas tester tous les cas. De mémoire, dans son labo de Manchester, il voulait vérifier qu'un circuit matériel (multiplicateur ?) fonctionnait correctement (même résultat qu'un programme). Il a évalué le nombre de cas à essayer, le temps nécessaire, et il s'est dit qu'il fallait faire autrement si on voulait prouver des trucs. D'où papier "checking a large routine" en 1949.

                                              https://fi.ort.edu.uy/innovaportal/file/20124/1/09-turing_checking_a_large_routine_earlyproof.pdf

                                              Ce qui donnera la méthode dite "des assertions" de Floyd, Hoare etc. et les techniques de vérification, formelle automatique ou pas, des programmes (et des circuits pour nos amis électroniciens digitaux).



                                              -
                                              Edité par michelbillaud 17 janvier 2020 à 17:51:28

                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                17 janvier 2020 à 18:06:22

                                                Voila un programme qui cherche les nombres premiers entre 0 et LAST_NBR, mais il donne 1 comme premier et oublie 2. Il fonctionne donc "à peu près".

                                                Tu l'emploierais, toi ? Moi pas.

                                                #include <math.h>
                                                #include <stdio.h>
                                                #include <stdbool.h>
                                                
                                                #define FIRST_NBR	0
                                                #define LAST_NBR	1000
                                                
                                                bool isPrime(int nbr) {
                                                	if((nbr & 1)==0)
                                                		return(false);
                                                	for(int i=3,end=(int)sqrt(nbr)+1;i<end;i+=2)
                                                		if(nbr%i==0)
                                                			return(false);
                                                	
                                                	return(true);
                                                }
                                                
                                                int main(void) {
                                                	int nbprime=0;
                                                	
                                                	for(int n=FIRST_NBR;n<=LAST_NBR;n++)
                                                		if(isPrime(n)) {
                                                			printf("%d ",n);
                                                			nbprime++;
                                                		}
                                                	printf("\n%d nombres premiers\n",nbprime);
                                                	
                                                	return(0);
                                                }
                                                	

                                                -
                                                Edité par edgarjacobs 17 janvier 2020 à 23:12:01

                                                • Partager sur Facebook
                                                • Partager sur Twitter

                                                On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

                                                  17 janvier 2020 à 18:25:17

                                                  Deja, quand je vois  nbr==2?true:false, je jette.

                                                  -
                                                  Edité par michelbillaud 17 janvier 2020 à 18:45:43

                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    17 janvier 2020 à 20:31:55

                                                    Il aurait été si facile de faire:
                                                    if(nbr < 2(  return(false);
                                                    if(nbr == 2)  return(true);
                                                    ...
                                                    Pour tester si nbr est pair, on a deux choix:
                                                    if((nbr & 1) ==0)  return(false);  // la plus rapide (mais on s'en fiche)
                                                    if((nbr % 2) == 0)  return(false);  // la plus orthodoxe
                                                    Quand je fais des tests, je commence par les cas faciles. Si ça ne marche déjà pas là, j'ai un sérieux problème.
                                                    Ensuite, j'essaie de trouver les cas "exotiques" ou "limites".
                                                    • Partager sur Facebook
                                                    • Partager sur Twitter

                                                    Le Tout est souvent plus grand que la somme de ses parties.

                                                    fonction qui supprime un caractère

                                                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                    • Editeur
                                                    • Markdown