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 qui retourne un tableau de char*


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Octobre 2007
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 30
    Par défaut Fonction qui retourne un tableau de char*
    saluts,

    nous sommes débutants en langage C.
    nous avons le programme suivant:
    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
     
    #include <stdio.h>
    #include <string.h>
     
    char *cavaco (char *x)
    {
    	for (int a = 0; a < strlen(x); a++) {
    		char *pars1 = (char *)malloc(a * sizeof(char));
    		char *pars2 = (char *)malloc((strlen(x) - a) * sizeof(char));
    		strncpy(pars1, x, a+1);
    		pars1[a+1] = '\0';
    		sprintf(pars2, "%s", &x[a+1]);
    		printf("%s %s\n", pars1, pars2);
    		free(pars1);
    		free(pars2);
    	}
    }
    int main(int argc, char *argv[])
    {
        cavaco("cheval");
        return 0;
    }
    c'est très simple. la fonction "cavaco" retourne toutes les possibles divisions d'un mot, comme "cheval", en deux parties:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    c heval
    ch eval
    che val
    chev al
    cheva l
    cheval
    la doute est: comment est-ce que nous pouvons faire la fonction retourner un array de strings - array de array de chars (char**) avec ces valeurs?
    par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    {"c heval",
    "ch eval",
    ...}
    et, donc, utiliser le valeur revenue?
    s'il vous plaît, souvenez-vous que la taille de chaque string dans l'array ne serait pas toujours strlen(x) + 1 (dans le cas de "cheval", ça serait 7, à cause du " " -> "c heval", "ch eval", ...), parce que nous pouvons vouloir changer la fonction "cavaco" pour diviser le mot de plus de façons différents, par exemple "che eval" (donc, il peut être plus divisions possibles, ça dépend des critères de division que nous pouvons vouloir utiliser).

    merci d'avance.

  2. #2
    Membre chevronné Avatar de Pierre Maurette
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    283
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 283
    Par défaut
    Bonjour,

    Je n'ai pas regardé attentivement votre code, mais je peux quand même vous faire une suggestion.
    Vous déclarez une structure contenant un int N et un char** mots qui sera compris comme un tableau de N char*.
    Votre fonction renvoie cette structure, et vous écrivez dans sa documentation que c'est l'appelant qui doit libérer. En fait, vous écrivez une fonction:
    void free_cavaco(struct machin)
    et vous marquez dans la documentation de caveco() que l'appelant devra appeler free_caveco() avec la structure renvoyée par caveco().
    Vous accédez aux mots par struct.mots[n], et pour libérer vous faites free() sur chaque élément (char*) de mots puis sur mots.
    Notez que accès et libération sont liés à des pointeurs qui peuvent être vus comme des clés suffisantes et nécessaires, il ne faut donc pas faire de free() dans la fonction cavaco().

  3. #3
    Membre averti
    Inscrit en
    Octobre 2007
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 30
    Par défaut
    Citation Envoyé par Pierre Maurette Voir le message
    Bonjour,

    Je n'ai pas regardé attentivement votre code, mais je peux quand même vous faire une suggestion.
    Vous déclarez une structure contenant un int N et un char** mots qui sera compris comme un tableau de N char*.
    Votre fonction renvoie cette structure, et vous écrivez dans sa documentation que c'est l'appelant qui doit libérer. En fait, vous écrivez une fonction:
    ...
    merci beaucoup pour votre résponse.
    nous sommes débutants, donc nous ne sommes pas sûrs de comment faire ce que vous avez dit. s'il vous plaît, est-ce que vous pouviez nous montrer un exemple écrit de ce méthode?
    merci d'avance.

  4. #4
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    - Si le mot comporte N caractères, alors il y a N manières de le couper en deux.
    - Les chaînes constituées des deux mots obtenus par cette coupure ont N+1 caractères (à cause du blanc qui est ajouté) sauf la dernière qui a N caractères.

    On peut donc :

    - Allouer un tableau tab de N pointeurs sur char

    - Pour i = 0 à i = N-2
    - allouer un tableau de N+2 char et mettre son adresse dans tab[i]
    - Copier la chaîne coupée en deux dans ce tableau : la première partie fait i+1 caractères, puis le blanc puis les caractères restants.
    - allouer un tableau de N+1 char et mettre son adresse dans tab[N-1]

    - copier la chaîne dans ce tableau

    Eventuellement, on peut allouer pour tab N+1 pointeurs sur char et mettre le dernier à NULL pour signifier que le tableau de chaînes est terminé

  5. #5
    Membre averti
    Inscrit en
    Octobre 2007
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 30
    Par défaut
    Citation Envoyé par diogene Voir le message
    - Si le mot comporte N caractères, alors il y a N manières de le couper en deux.
    - Les chaînes constituées des deux mots obtenus par cette coupure ont N+1 caractères (à cause du blanc qui est ajouté) sauf la dernière qui a N caractères.

    On peut donc :
    ...
    merci, nous irons essayer d'utiliser cette idée, mais le problème est que il n'y aura pas toujours N divisions possibles (parce que nous pouvons vouloir diviser le mot de différentes manières - comme "che eval" - , en outre le manière que nous avons montré - c heval, ch eval, ...).

  6. #6
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Citation Envoyé par pc2-bresil Voir le message
    merci, nous irons essayer d'utiliser cette idée, mais le problème est que il n'y aura pas toujours N divisions possibles (parce que nous pouvons vouloir diviser le mot de différentes manières - comme "che eval" - , en outre le manière que nous avons montré - c heval, ch eval, ...).
    Mais "che eval" n'est pas "cheval" coupé en 2. Que signifie précisément dans votre problème l'expression "diviser en deux parties" ?

  7. #7
    Membre chevronné Avatar de Pierre Maurette
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    283
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 283
    Par défaut
    Citation Envoyé par pc2-bresil Voir le message
    merci beaucoup pour votre résponse.
    nous sommes débutants, donc nous ne sommes pas sûrs de comment faire ce que vous avez dit. s'il vous plaît, est-ce que vous pouviez nous montrer un exemple écrit de ce méthode?
    merci d'avance.
    A corriger en fonction de votre problème réel. Attention, "cheval" ne fait pas partir des retours. Penser à tester les malloc(). Ecriture à simplifier si syntaxe C99.

    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    typedef struct {
        int Nb;
        char** mots1;
        char** mots2;
        } scaveco;
     
     
    scaveco cavaco(char *x)
    {
    	int a = 0;
    	scaveco ret;
    	ret.Nb = strlen(x) - 1;
    	ret.mots1 = malloc(ret.Nb * sizeof *ret.mots1);
    	ret.mots2 = malloc(ret.Nb * sizeof *ret.mots2);
    	for (a = 0; a < ret.Nb; a++) {
    		ret.mots1[a] = malloc(a * sizeof **ret.mots1);
    		ret.mots2[a] = malloc((ret.Nb - a) * sizeof **ret.mots2);
    		strncpy(ret.mots1[a], x, a+1);
    		ret.mots1[a][a+1] = '\0';
    		sprintf(ret.mots2[a], "%s", &x[a+1]);
    	}
    	return ret;
    }
     
    void cavaco_free(scaveco s)
    {
    	int a = 0;
    	for (a = 0; a < s.Nb; a++) {
    	    free(s.mots1[a]);
    	    free(s.mots2[a]);
    	}
    	free(s.mots1);
    	free(s.mots2);
    }
     
     
    int main(int argc, char *argv[])
    {
        scaveco result = cavaco("cheval");
        int a;
        for(a = 0; a < result.Nb; a++){
            puts(result.mots1[a]);
            puts(result.mots2[a]);
        }
        cavaco_free(result);
        return EXIT_SUCCESS;
    }

  8. #8
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Citation Envoyé par Pierre Maurette Voir le message
    A corriger en fonction de votre problème réel. Attention, "cheval" ne fait pas partir des retours. Penser à tester les malloc(). Ecriture à simplifier si syntaxe C99.

    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    typedef struct {
        int Nb;
        char** mots1;
        char** mots2;
        } scaveco;
     
     
    scaveco cavaco(char *x)
    {
    	int a = 0;
    	scaveco ret;
    	ret.Nb = strlen(x) - 1;
    	ret.mots1 = malloc(ret.Nb * sizeof *ret.mots1);
    	ret.mots2 = malloc(ret.Nb * sizeof *ret.mots2);
    	for (a = 0; a < ret.Nb; a++) {
    		ret.mots1[a] = malloc(a * sizeof **ret.mots1);
    		ret.mots2[a] = malloc((ret.Nb - a) * sizeof **ret.mots2);
    		strncpy(ret.mots1[a], x, a+1);
    		ret.mots1[a][a+1] = '\0';
    		sprintf(ret.mots2[a], "%s", &x[a+1]);
    	}
    	return ret;
    }
     
    void cavaco_free(scaveco s)
    {
    	int a = 0;
    	for (a = 0; a < s.Nb; a++) {
    	    free(s.mots1[a]);
    	    free(s.mots2[a]);
    	}
    	free(s.mots1);
    	free(s.mots2);
    }
     
     
    int main(int argc, char *argv[])
    {
        scaveco result = cavaco("cheval");
        int a;
        for(a = 0; a < result.Nb; a++){
            puts(result.mots1[a]);
            puts(result.mots2[a]);
        }
        cavaco_free(result);
        return EXIT_SUCCESS;
    }
    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    typedef struct 
    {
       size_t Nb;
       char **mots1;
       char **mots2;
    } scaveco;
     
    void cavaco_free(scaveco **s);
    scaveco *cavaco(char const *x);
     
    int main (void)
    {
        scaveco *result = cavaco("cheval");
        if (result != NULL)
        {
           size_t i = 0;
           for(i = 0; i < result->Nb; i++)
               printf ("%s %s\n",result->mots1[i], result->mots2[i]);
     
           cavaco_free (&result);
        }
        return EXIT_SUCCESS;
    }
     
    scaveco *cavaco(char const *x)
    {
       scaveco *ret = NULL;
     
       if (x != NULL)
       {
          int err = 0;
     
          ret = malloc (sizeof *ret);
          if (ret != NULL)
          {    
             ret->Nb = strlen (x) - 1;
             ret->mots1 = malloc (ret->Nb * sizeof *ret->mots1);
             ret->mots2 = malloc (ret->Nb * sizeof *ret->mots2);
     
             if (ret->mots1 != NULL && ret->mots2 != NULL)
             {
                size_t i = 0;  
                for (i = 0; i < ret->Nb; i++) 
                {
                   ret->mots1[i] = malloc (i * sizeof **ret->mots1);
                   ret->mots2[i] = malloc ((ret->Nb - i) * sizeof **ret->mots2);
                   if (ret->mots1[i] != NULL && ret->mots2[i] != NULL)
                   {
                      strncpy (ret->mots1[i], x, i+1);
                      ret->mots1[i][i+1] = 0;
                      sprintf (ret->mots2[i], "%s", x + i + 1);
                   }
                   else
                   {
                      err = 1;
                      break;
                   }
                }
             }
             else
                err = 2;
          }
     
          if (err)
             cavaco_free (&ret);
       }
       return ret;
    }
     
    void cavaco_free(scaveco **s)
    {
       if (s != NULL)
       {
          if (*s != NULL)
          {
             size_t i = 0;
     
             if ((*s)->mots1 != NULL)
             {
                for (i = 0; i < (*s)->Nb; i++) 
                {
                   if ((*s)->mots1[i] != NULL)
                      free ((*s)->mots1[i]), (*s)->mots1[i] = NULL;
                }
                free ((*s)->mots1), (*s)->mots1 = NULL;
             }
     
             if ((*s)->mots2 != NULL)
             {
                for (i = 0; i < (*s)->Nb; i++) 
                {
                   if ((*s)->mots2[i] != NULL)
                      free ((*s)->mots2[i]), (*s)->mots2[i] = NULL;
                }
                free ((*s)->mots2), (*s)->mots2 = NULL;
             }
     
             free (*s), *s = NULL;
          }
       }
    }

  9. #9
    Membre averti
    Inscrit en
    Octobre 2007
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 30
    Par défaut
    merci beaucoup à vous.
    mais - nous vous ennuierons de nouveau - il y a encore un problème.
    c'est la ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ret->Nb = strlen (x) - 1;
    est-ce qu'il y a une manière de ne pas présumer que le nombre de résultats serait toujours strlen(x) - 1? par exemple, si nous voulons ajouter autres possibilités de division (que dépendent du mots1[a] et mots2[a] courant, et, donc, de nombre imprévisible si pas à l'intérieur du for).
    est-ce que nous pouvons changer le nombre de résultats dynamiquement d'après necessité, en rédimensionner les tailles de ret.mots1 et ret.mots2 dans le for? quelque chose du genre (initialiser ret.Nb comme 1 en premier, par exemple):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ret.mots1 = realloc((ret.Nb++) * sizeof *ret.mots1);
    ret.mots2 = realloc((ret.Nb++) * sizeof *ret.mots2);
    nous sommes débutants, donc ce peut ne faire pas sens...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Tableaux] Fonction qui retourne un tableau
    Par benooiit dans le forum Langage
    Réponses: 2
    Dernier message: 05/01/2007, 01h50
  2. Réponses: 6
    Dernier message: 22/09/2006, 18h17
  3. Fonction qui retourne un tableau ou 2 variables ? possible ou non
    Par jiojio dans le forum VB 6 et antérieur
    Réponses: 45
    Dernier message: 05/06/2006, 15h00
  4. [VB] Fonction qui retourne un tableau
    Par ptitsoleil87 dans le forum VB 6 et antérieur
    Réponses: 11
    Dernier message: 24/12/2005, 10h52
  5. Fonction qui retourne un tableau
    Par _lara_ dans le forum ASP
    Réponses: 6
    Dernier message: 24/05/2004, 15h06

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