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
?
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
?
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).
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).
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.
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.