Partage
  • Partager sur Facebook
  • Partager sur Twitter

retourner une chaine en étoile

cacher un mot

    14 juin 2021 à 17:36:28

    bonjour je voudrais faire une fonction qui prend une chaine de caractères et la retourne en une chaine  de caractères en etoile on dirait un mot de passe

    je sais que l'algorithme est plus au moins facile mais je rencontre des problèmes au niveau des fonctions le retour ect..

    d'abord j'ai essayé de faire une fonction avec le prototype char* (char *ch) qui retourne une chaine mais c'a na pas marche 

    je voudrais savoir s'il est possible de retourner une chaine d'abord après j'ai change en une fonctionn void mais je rencontre encore des problèmes

    voci le code:

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<ctype.h>
    void etoile(char *car,char *ch)
    {
        int l,i;
        l=strlen(car);
        for(i=1;i<=l;i++)
            strcat(ch,"*");
    }void main()
    {
        char *c="marron",*s;
        s=(char*)malloc(strlen(c)*sizeof(char));
        s="";
        etoile(c,s);
        printf("%s",s);
        free(s);
    }
    



    -
    Edité par WassimTaktak 14 juin 2021 à 17:50:38

    • Partager sur Facebook
    • Partager sur Twitter
      14 juin 2021 à 17:43:50

      Bonjour,

      Le message qui suit est une réponse automatique activée par un membre de l'équipe. Les réponses automatiques leur permettent d'éviter d'avoir à répéter de nombreuses fois la même chose, ce qui leur fait gagner du temps et leur permet de s'occuper des sujets qui méritent plus d'attention.
      Nous sommes néanmoins ouverts et si vous avez une question ou une remarque, n'hésitez pas à contacter la personne en question par Message Privé.

      Pour plus d'informations, nous vous invitons à lire les règles générales du forum

      Merci de colorer votre code à l'aide du bouton Code

      Les forums d'Openclassrooms disposent d'une fonctionnalité permettant de colorer et mettre en forme les codes source afin de les rendre plus lisibles et faciles à manipuler par les intervenants. Pour cela, il faut utiliser le bouton Code de l'éditeur, choisir un des langages proposés et coller votre code dans la zone prévue. Si vous utilisez l'éditeur de messages en mode Markdown, il faut utiliser les balises <pre class="brush: cpp;">Votre code ici</pre>.

      Merci de modifier votre message d'origine en fonction.

      Liens conseillés

      • Partager sur Facebook
      • Partager sur Twitter
        14 juin 2021 à 18:29:44

        Tu n'as pas de warning sur la variable 's'?
        char *s = malloc(strlen(c) + 1);   // le +1 est requis pour la fin de chaîne.
        Pourquoi ne pas donner seulement le pointeur vers s et la longueur à ta fonction.
        Pourquoi utiliser strcat au lieu d'une simple assignation?
        et ne pas oublier la fin de chaîne.
        • Partager sur Facebook
        • Partager sur Twitter

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

          14 juin 2021 à 23:21:06

          Une grosse erreur :

          Dans ta fonction main tu créés un pointeur nommé s, puis tu lui affectes l'adresse d'un bloc mémoire alloué avec malloc, jusque là tout va bien !

          Ensuite à ce même pointeur, tu lui affectes l'adresse d'une chaîne de caractère s=""; tu perds donc l'adresse de ton allocation !

          • Partager sur Facebook
          • Partager sur Twitter
            15 juin 2021 à 1:58:34

            @rouloude:
            Oups! Celle-là m'a échappé.
            Si je remplace par:
                *s = '\0';
            Ça semble marcher parce que je suis chanceux. Mais aucun espace n'est réservé pour la fin de chaîne.
            Et  sizeof(char) est inutile car ça vaut toujours 1.
            Et je ne sais pas où le PO a pris le truc du strcat()
            La conception de la fonction est plus que bizarre ...
            Puisqu'on a besoin de la longueur de la chaîne de comparaison, pourquoi ne pas l'utiliser en paramètre de la fonction au lieu de recalculer cette longueur dans la fonction.
            • Partager sur Facebook
            • Partager sur Twitter

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

              15 juin 2021 à 10:28:00

              Un printf pourrait suffire

              #include <stdio.h>
              #include <string.h>
              
              int main(void)
              {
                const char mot[] = "ANTICONSTITUTIONNELLEMENT";
                printf("%.*s\n", strlen(mot), "*************************");
              }

              mais cela ne tient pas des lettres déjà trouvées. Si le mot à deviner est "MARRON" et que l'utilisateur à trouvé la lettre 'R' alors la chaine devrait être

              **RR**



              -
              Edité par magma 15 juin 2021 à 10:37:57

              • Partager sur Facebook
              • Partager sur Twitter
                15 juin 2021 à 15:41:35

                @magma:
                WassimTaktak veut remplir son tableau avec des '*'. Le but n'est pas de seulement l'afficher.
                On pourrait utiliser un sprintf mais c'est trop lourd
                 

                Il y a environ 21 heur

                • Partager sur Facebook
                • Partager sur Twitter

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

                  15 juin 2021 à 17:51:15

                  WassimTaktak : en fait ça ressemble à la fonction 'strcpy', sauf qu'au lieu de copier chaque caractère de la chaîne source dans la chaîne cible, on recopie un '*'. Je crois qu'on trouve facilement des codes sources pour 'strcpy'. Il suffit d'en trouver un et de l'adapter.
                  • Partager sur Facebook
                  • Partager sur Twitter
                    15 juin 2021 à 18:04:20

                    @robun:
                    Je ne crois pas que ce soit la bonne approche. Qu'y a-t-il de plus facile que de remplir un tableau avec une certaine valeur?
                    -
                    void etoile(char *ch, int lg) {
                        for(int i=0; i < lg; i++) {
                            ch[i] = '*';
                        }
                        ch[lg] = '\0';
                    }
                    • Partager sur Facebook
                    • Partager sur Twitter

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

                      15 juin 2021 à 18:19:30

                      sinon :

                      char *repeat_char(size_t n, int ch)
                      {
                          char *res=malloc( n+1 );
                          if (res) {
                              memset(res, ch, n);
                              res[n]=0;
                          }
                          return res;
                      }



                      • Partager sur Facebook
                      • Partager sur Twitter
                        15 juin 2021 à 18:38:49

                        Ou dans l'optique du PO, en supposant que la chaîne de départ se termine par un '\0':
                        -
                        void etoile(char *car, char *ch) {
                            while(*car != '\0') {
                                *ch = '*';
                                car++;
                                ch++;
                            }
                            *ch = '\0';
                        }
                        • Partager sur Facebook
                        • Partager sur Twitter

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

                          15 juin 2021 à 21:14:24

                          PierrotLeFou a écrit:

                          @robun:
                          Je ne crois pas que ce soit la bonne approche. Qu'y a-t-il de plus facile que de remplir un tableau avec une certaine valeur?
                          -

                          J'étais intervenu parce que WassimTaktak utilisait la fonction 'strcat'. Je trouvais ça compliqué, et je suis tout à fait d'accord que le plus simple est une boucle comme tu l'as montré. Justement, une fonction comme 'strcpy' contient  exactement ce genre de boucle, ça pouvait donner une idée...

                          Par contre je reprends ta dernière version pour la traduire en version sans pointeur (j'aime pas les pointeurs... ;) ), probablement plus simple pour quelqu'un qui débute (pour moi en tout cas) :

                          void etoile(char car[], char ch[]) {
                              int i = 0;
                              while(car[i] != '\0') {
                                  ch[i] = '*';
                                  i++;
                              }
                              ch[i] = '\0';
                          }
                          

                          D'ailleurs est-ce vraiment moins efficace ? (C'est une vraie question : j'ai un seul ++, mais peut-être que l'accès direct à la position i est plus coûteux que juste le décalage de position ?)

                          -----------

                          Je viens de tester les deux version : chaque programme fait un milliard de fois la boucle ci-dessus directement dans le 'main' (pour ne pas compter le temps passé à gérer la pile d'appel de la fonction). J'ai utilisé la commande 'time' :

                          • Version Pierrot avec pointeurs :
                          real    0m2,611s
                          user    0m2,610s
                          sys     0m0,000s
                          • Ma version avec indice de boucle :
                          real    0m39,312s
                          user    0m39,283s
                          sys     0m0,004s

                          Bon, les pointeurs, c'est plus efficace ! (Hélas...)

                          -
                          Edité par robun 16 juin 2021 à 11:06:59

                          • Partager sur Facebook
                          • Partager sur Twitter
                            16 juin 2021 à 3:52:43

                            Je ne connais pas l'assembleur x86 ni comment le compilateur a traduit ton test.
                            Intuitivement, ajouter 1 à un registre est assez rapide (tel que car++ ou ch++)
                            Sur de vieilles machines, on appelait ça un "replace add one"
                            Adresser une position demande d'aller chercher l'indice (qui peut être dans un registre) et l'ajouter à l'adresse de base.
                            Tu le fais deux fois: car[i] et ch[i]. Je suppose que c'est plus compliqué.
                            Tu peux incrémenter l'indice (i++) avec un replace add one.
                            J'ai refait le test en utilisant clock() sur Windows. La difféerence est moins frappante:
                            robun: 0.432 secondes                                                                                                  
                            pierrot: 0.344 secondes                                                                                                 
                            Ça m'apparaît plus réaliste ...
                            • Partager sur Facebook
                            • Partager sur Twitter

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

                              16 juin 2021 à 9:41:04

                              Même si robun à l'impression de ne pas utiliser de pointeur, ce sont quand même des pointeurs qu'il utilise. Dans les deux cas la fonction reçoit l'adresse des tableaux. 

                              La différence c'est que robun utilise un indice qui sera ajouté au pointeur pour obtenir l'adresse de la case du tableau et que Pierrot incrémente directement le pointeur pour passer à l'adresse de la case suivante.

                              Compilé avec l'optimisation maximum, il et possible que les deux codes générés soit identique.

                              • Partager sur Facebook
                              • Partager sur Twitter
                                16 juin 2021 à 11:05:32

                                rouloude a écrit:

                                Même si robun à l'impression de ne pas utiliser de pointeur, ce sont quand même des pointeurs qu'il utilise. Dans les deux cas la fonction reçoit l'adresse des tableaux. 

                                [...]


                                En effet, la notation T[i] où T est un tableau et i un entier n'est que du sucre syntaxique pour ( *( (T)+(i) ) ) où T est transformé en pointeur sur le premier élément. On peut même remplacer tout T[i] par i[T] qui est totalement équivalent.
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  16 juin 2021 à 11:10:52

                                  Ah oui, c'est vrai... Donc j'ai juste comparé p+i avec p++.

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    16 juin 2021 à 15:26:49

                                    La différence est que tu fais 2 p+i et un i++ alors que je fais 2 p++ et pas de i++ :)
                                    @rouloude: j'ai compilé avec -O3
                                    (si vous voulez mon code affreux, je peux vous le donner ...)
                                    • Partager sur Facebook
                                    • Partager sur Twitter

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

                                    retourner une chaine en étoile

                                    × 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