98 votes

Comment copier un tableau de chars en C ?

En C, j'ai deux tableaux de chars :

char array1[18] = "abcdefg";
char array2[18];

Comment copier la valeur de array1 a array2 ? Puis-je simplement faire ceci : array2 = array1 ?

100voto

aymericbeaumet Points 1692

Vous ne pouvez pas faire directement array2 = array1 car dans ce cas, vous manipulez les adresses des tableaux ( char * ) et non de leurs valeurs internes ( char ).

Ce que vous voulez faire, conceptuellement, c'est itérer à travers tous les caractères de votre source ( tableau1 ) et les copier vers la destination ( tableau2 ). Il existe plusieurs façons de procéder. Par exemple, vous pouvez écrire une simple boucle for, ou utiliser la fonction memcpy .

Ceci étant dit, la méthode recommandée pour les chaînes de caractères est d'utiliser strncpy . Il permet d'éviter les erreurs courantes qui se traduisent, par exemple, par une perte de temps, débordements de tampon (ce qui est particulièrement dangereux si array1 est rempli à partir de l'entrée de l'utilisateur : clavier, réseau, etc). Ainsi :

// Will copy 18 characters from array1 to array2
strncpy(array2, array1, 18);

Comme @Prof. Falken l'a mentionné dans un commentaire, strncpy peut être mauvais . Assurez-vous que votre tampon cible est suffisamment grand pour contenir le tampon source (y compris le fichier \0 à la fin de la chaîne).

41voto

unknown Points 352

Si vos tableaux ne sont pas des tableaux de chaînes de caractères, utilisez : memcpy(array2, array1, sizeof(array2));

27voto

Prof. Falken Points 10242

Si vous voulez vous prémunir contre les chaînes non terminées, qui peuvent causer toutes sortes de problèmes, copiez votre chaîne comme ceci :

char array1[18] = {"abcdefg"};
char array2[18];

size_t destination_size = sizeof (array2);

strncpy(array2, array1, destination_size);
array2[destination_size - 1] = '\0';

Cette dernière ligne est en fait importante, parce que strncpy() n'est pas toujours nullité de la terminaison ficelles. (Si le tampon de destination est trop petit pour contenir la totalité de la chaîne source, sntrcpy() ne terminera pas de manière nulle la chaîne de destination).

La page de manuel de strncpy() indique même que "Avertissement : S'il n'y a pas d'octet nul parmi les n premiers octets de src, la chaîne placée dans dest ne sera pas à terminaison nulle."

La raison pour laquelle strncpy() se comporte de cette manière un peu étrange, est qu'il n'était pas prévu à l'origine comme un moyen sûr de copier des chaînes de caractères.

Une autre façon est d'utiliser snprintf() comme un remplacement sûr de strcpy() :

snprintf(array2, destination_size, "%s", array1);

(Merci <a href="https://stackoverflow.com/users/315052/jxh">jxh </a>pour le conseil).

10voto

jxh Points 32720

Comme d'autres l'ont noté, les chaînes de caractères sont copiées avec strcpy() ou ses variantes. Dans certains cas, vous pouvez utiliser snprintf() également.

Vous ne pouvez affecter les tableaux comme vous le souhaitez que dans le cadre d'une affectation de structure :

typedef struct { char a[18]; } array;
array array1 = { "abcdefg" };
array array2;

array2 = array1;

Si vos tableaux sont passés à une fonction, il semblera que vous êtes autorisé à les assigner, mais ce n'est qu'un accident de la sémantique. En C, un tableau se décompose en un type de pointeur avec la valeur de l'adresse du premier membre du tableau, et ce pointeur est ce qui est transmis. Ainsi, votre paramètre de tableau dans votre fonction n'est en fait qu'un pointeur. L'affectation est juste une affectation de pointeur :

void foo (char x[10], char y[10]) {
    x = y;    /* pointer assignment! */
    puts(x);
}

Le tableau lui-même reste inchangé après le retour de la fonction.

Cette sémantique de "décroissance vers la valeur du pointeur" pour les tableaux est la raison pour laquelle l'affectation ne fonctionne pas. La valeur l a le type tableau, mais la valeur r est le type pointeur décomposé, donc l'affectation est entre des types incompatibles.

char array1[18] = "abcdefg";
char array2[18];
array2 = array1; /* fails because array1 becomes a pointer type,
                    but array2 is still an array type */

Quant à la raison pour laquelle la sémantique "decay to pointer value" a été introduite, c'était pour obtenir une compatibilité de code source avec le prédécesseur de C. Vous pouvez lire Le développement du langage C pour les détails.

8voto

unwind Points 181987

Vous ne pouvez pas assigner des tableaux, les noms sont des constantes qui ne peuvent pas être modifiées.

Vous pouvez copier le contenu avec :

strcpy(array2, array1);

en supposant que la source est une chaîne valide et que la destination est suffisamment grande, comme dans votre exemple.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X