web-dev-qa-db-fra.com

Comment puis-je retourner un tableau de caractères à partir d'une fonction en C?

est-ce que c'est possible? Disons que je veux renvoyer un tableau de deux caractères

char arr[2];
arr[0] = 'c';
arr[1] = 'a';

à partir d'une fonction. Quel type dois-je même utiliser pour la fonction? Est-ce que mon seul choix est d'utiliser des pointeurs et d'annuler la fonction? Jusqu'à présent, j'ai essayé d'avoir une fonction char * ou un char []. Apparemment, vous ne pouvez avoir que des fonctions de char (* []). La seule raison pour laquelle je veux éviter d'utiliser des pointeurs est le fait que la fonction doit se terminer lorsqu'elle rencontre un "retour quelque chose"; parce que la valeur de "quelque chose" est un tableau de caractères (pas une chaîne!) qui pourrait changer de taille en fonction des valeurs que je transmets à la fonction par le biais de la fonction principale. Merci à tous ceux qui répondent à l’avance.

6
user5042178

Vous avez plusieurs options:

1) Allouez votre tableau sur le tas en utilisant malloc(), et renvoyez un pointeur sur celui-ci. Vous devrez également suivre vous-même la longueur:

void give_me_some_chars(char **arr, size_t *arr_len)
{
    /* This function knows the array will be of length 2 */
    char *result = malloc(2);

    if (result) {
        result[0] = 'c';
        result[1] = 'a';
    }

    /* Set output parameters */
    *arr = result;
    *arr_len = 2;
}

void test(void)
{
    char *ar;
    size_t ar_len;
    int i;

    give_me_some_chars(&ar, &ar_len);

    if (ar) {
        printf("Array:\n");
        for (i=0; i<ar_len; i++) {
            printf(" [%d] = %c\n", i, ar[i]);
        }
        free(ar);
    }
}

2) Alloue de l'espace pour le tableau sur la pile du appelant, et laissez la fonction appelée le remplir:

#define ARRAY_LEN(x)    (sizeof(x) / sizeof(x[0]))

/* Returns the number of items populated, or -1 if not enough space */
int give_me_some_chars(char *arr, int arr_len)
{
    if (arr_len < 2)
        return -1;

    arr[0] = 'c';
    arr[1] = 'a';

    return 2;
}

void test(void)
{
    char ar[2];
    int num_items;

    num_items = give_me_some_chars(ar, ARRAY_LEN(ar));

    printf("Array:\n");
    for (i=0; i<num_items; i++) {
        printf(" [%d] = %c\n", i, ar[i]);
    }
}

NE PAS ESSAYER DE LE FAIRE

char* bad_bad_bad_bad(void)
{
    char result[2];      /* This is allocated on the stack of this function
                            and is no longer valid after this function returns */

    result[0] = 'c';
    result[1] = 'a';

    return result;    /* BAD! */
}

void test(void)
{
    char *arr = bad_bad_bad_bad();

    /* arr is an invalid pointer! */
}
14
Jonathon Reinhart

Vous pouvez renvoyer un pointeur pour le tableau à partir d'une fonction. Toutefois, vous ne pouvez pas renvoyer de pointeurs vers des tableaux locaux, la référence sera perdue.

Donc vous avez 3 options:

  1. Utilisez une variable globale:

    char arr[2];
    
    char * my_func(void){
        arr[0] = 'c';
        arr[1] = 'a';
        return arr;
    }
    
  2. Utiliser l'attribution dinamique (l'appelant sera responsable de libérer le pointeur après l'avoir utilisé, précisez-le dans votre documentation)

    char * my_func(void){
    
        char *arr;    
        arr = malloc(2);
        arr[0] = 'c';
        arr[1] = 'a';
    
        return arr;
    }
    
  3. Demander à l'appelant d'allouer le tableau et de l'utiliser comme référence (ma recommandation)

    void my_func(char * arr){
    
        arr[0] = 'c';
        arr[1] = 'a';
    }
    

si vous avez vraiment besoin de la fonction pour retourner le tableau, vous pouvez retourner la même référence que:

char * my_func(char * arr){
    arr[0] = 'c';
    arr[1] = 'a';
    return arr;
}
0
DSLima90

Vous pouvez passer le tableau à la fonction et laisser la fonction le modifier, comme ceci

void function(char *array)
 {
    array[0] = 'c';
    array[1] = 'a';
 }

et alors

char array[2];

function(array);
printf("%c%c\n", array[0], array[1]);

Si vous le souhaitez comme valeur de retour, vous devez utiliser l'allocation de mémoire dynamique,

char *function(void)
 {
    char *array;

    array = malloc(2);
    if (array == NULL)
        return NULL;
    array[0] = 'c';
    array[1] = 'a';

    return array;
 }

puis

char *array = function();
printf("%c%c\n", array[0], array[1]);
/* done using `array' so free it because you `malloc'ed it*/
free(array);

Note importante :

Vous devez être conscient du fait que le tableau rempli ci-dessus n'est pas une chaîne, vous ne pouvez donc pas le faire par exemple.

printf("%s\n", array);

parce que "%s" s'attend à ce qu'une chaîne correspondante soit transmise, et en c un tableau n'est pas une chaîne à moins que son dernier caractère soit '\0'. Ainsi, pour une chaîne de 2 caractères, vous devez allouer de l'espace à 3 caractères et définir le dernier à '\0'.

0
Iharob Al Asimi

Puisque vous avez une taille prédéterminée de votre tableau, vous pouvez effectivement renvoyer le tableau si vous l’enveloppez avec une structure:

struct wrap
{
    char a[2] ;
} ;

struct wrap Get( void )
{
    struct wrap w = { 0 } ;

    w.a[0] = 'c';
    w.a[1] = 'a';

return w ;
}
0
this