IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Fonction renvoyant une string


Sujet :

C

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut Fonction renvoyant une string
    Bonjour, ce message fait suite au poste http://www.developpez.net/forums/sho...d.php?t=140630 où j'ai une fonction qui transforme ma chaine de caractères en majuscule :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    #include <ctype.h>
     
     void strtoupper(char *s)
     {
        if (s)
        {
           while(*s)
           {
              *s = toupper(*s);
              s++;
           }
        }
     }
    maintenant, je désire que ma string s ne soit pas modifiée donc voici ce que j'ai fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<ctype.h>
     
    char * strtoupper(char * s)
    {
    /* converts the string s with all these chars in capital letter */
     
      char * str=strdup(s);
      printf("str = %s\n",str);
     
      while(*str!='\0')
      {
        printf("*str = %c\n",*str);
        *str=toupper(*str);
        ++str;
      }
      printf("str = %s\n",str);
      return str;
    }
     
    int main()
    {
      char s1[]="c7H15-2abc";
      char * s2=strtoupper(s1);
      printf("s2 = %s\n",s2);
      free(s2); s2=NULL;
      return 0;
    }
    mais là il y a un bug lors de mon free(s2). Pourtant après un strdup il faut faire un free non ?

    Merci

  2. #2
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    Le free ne fonctionne qu'avec une adrese allouée par malloc, ce qui n'est pas le cas pour s2.
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  3. #3
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    En effet, il faut faire un free() apres strdup(), mais il faut envoyer a free() le pointeur non-modifie, tel qu'attribue par strdup(). Dans ta fonction, tu incrementes str...
    Il faut que tu utilises une variable temporaire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    str = strdup(s);
    if (str)
    {
       char *p = str;
       ...
          p++;
       ...
    }
    return str;

  4. #4
    Membre éclairé Avatar de crocodilex
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    697
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 697
    Points : 858
    Points
    858
    Par défaut
    Tu dois faire un free du pointeur renvoyé par strdup. Or dans ta fonction tu incrémentes ton pointeur. Ca ne risque pas de marcher.
    Software Failure. Press left mouse button to continue.
    Guru Meditation #0100000C.000FE800

  5. #5
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par salseropom
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    #include <ctype.h>
     
     void strtoupper(char *s)
    Et j'ajoute que 'strtoupper' est un identificateur réservé.

    http://emmanuel-delahaye.developpez....htm#id_reserve

    'str_toupper' est correct.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<ctype.h>
     
    char * str_toupper(char const * s)
    {
       /* converts the string s with all these chars in capital letter */
     
       char * str = strdup(s);
       if (str != NULL)
       {
          char *p = str;
     
          while (*p != '\0')
          {
             *p = toupper(*p);
             p++;
          }
       }
       return str;
    }
     
    int main()
    {
       char s1[] = "c7H15-2abc";
       printf("s1 = '%s'\n", s1);
       char * s2 = str_toupper(s1);
     
       if (s2 != NULL)
       {
          printf("s2 = '%s'\n", s2);
          free(s2), s2 = NULL;
       }
       return 0;
    }
    Pas de Wi-Fi à la maison : CPL

  6. #6
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    Oups, desole d'avoir utilise un idenficateur reserve. Ils sont chiant a l'ISO de choper tous les noms simples!

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    Bonjour, merci de vos explications. Voici donc ma nouvelle fonction qui marche

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<ctype.h>
     
    char * str_toupper(char * s)
    {
    /* converts the string s with all these chars in capital letter */
     
      char * str_=strdup(s);
      unsigned short length=strlen(str_),i;
      char str[length];
      strcpy(str,str_);
     
      for(i=0;i<length;++i) str[i]=toupper(str[i]);
      strcpy(str_,str);
      return str_;
    }
     
    int main()
    {
      char s1[]="c7H15-2abc";
      char * s2=str_toupper(s1);
      printf("s2 = %s\n",s2);
      free(s2); s2=NULL;
      return 0;
    }
    ma fonction n'est sûrement pas optimisée (car il y a deux copies) mais au moins elle marche...
    Merci.

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    oups, désolé, je n'avais pas vu la fin de ton post Emmanuel. Ta fonction est bcp mieux ! Merci.

  9. #9
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par salseropom
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
      char * str_=strdup(s);
      unsigned short length=strlen(str_),i;
      char str[length];
      strcpy(str,str_);
    Merci.
    Tu n'as absolument pas besoin de ce tableau intermédiaire (VLA, en plus : status 'broken' chez gcc !)

    2 corrections (identiques) ont été publiées.
    Pas de Wi-Fi à la maison : CPL

Discussions similaires

  1. Réponses: 2
    Dernier message: 14/06/2010, 15h21
  2. [AC-2003] Fonction retournant une string dans un état
    Par yupyupxav dans le forum IHM
    Réponses: 2
    Dernier message: 28/02/2010, 18h41
  3. Problème avec fonction renvoyant une "Nested Table"
    Par Sunchaser dans le forum PL/SQL
    Réponses: 4
    Dernier message: 20/05/2009, 17h19
  4. fonction renvoyant une matrice
    Par sub-0 dans le forum Débuter
    Réponses: 6
    Dernier message: 31/12/2008, 17h59
  5. fonction manipulant une string
    Par salseropom dans le forum C
    Réponses: 16
    Dernier message: 21/02/2006, 13h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo