85 votes

Affectation de chaînes de caractères à des tableaux de caractères

Je suis un peu surpris par ce qui suit.

Exemple 1 :

char s[100] = "abcd"; // declare and initialize - WORKS

Exemple 2 :

char s[100]; // declare
s = "hello"; // initalize - DOESN'T WORK ('lvalue required' error)

Je me demande pourquoi la deuxième approche ne fonctionne pas. Il semble naturel qu'elle le fasse (elle fonctionne avec d'autres types de données) ? Quelqu'un pourrait-il m'expliquer la logique derrière tout cela ?

75voto

shoosh Points 34322

Lors de l'initialisation d'un tableau, C vous permet de le remplir de valeurs. Ainsi,

char s[100] = "abcd";

est fondamentalement la même chose que

int s[3] = { 1, 2, 3 };

mais cela ne vous permet pas de faire l'affectation puisque s est un tableau et non un pointeur libre. La signification de

s = "abcd" 

est d'assigner la valeur du pointeur de abcd a s mais tu ne peux pas changer s car alors rien ne pointera vers le tableau.
Cela peut fonctionner et fonctionne si s est un char* - un pointeur qui peut pointer vers n'importe quoi.

Si vous voulez copier la chaîne, utilisez simplement strcpy .

61voto

dwc Points 12676

Les chaînes de caractères n'existent pas en C. En C, les chaînes de caractères sont des tableaux unidimensionnels contenant les éléments suivants char terminé par un caractère nul \0 . Puisque vous ne pouvez pas assigner des tableaux en C, vous ne pouvez pas non plus assigner des chaînes de caractères. Le littéral "hello" est du sucre syntaxique pour const char x[] = {'h','e','l','l','o','\0'};

La manière correcte serait :

char s[100];
strncpy(s, "hello", 100);

ou mieux encore :

#define STRMAX 100
char    s[STRMAX];
size_t  len;
len = strncpy(s, "hello", STRMAX);

14voto

Sparr Points 5796

L'initialisation et l'affectation sont deux opérations distinctes qui utilisent ici le même opérateur ("=").

3voto

Matt Davis Points 22019
1    char s[100];
2    s = "hello";

Dans l'exemple que vous avez fourni, s est en fait initialisé à la ligne 1, et non à la ligne 2. Même si vous ne lui avez pas attribué de valeur explicitement à ce stade, le compilateur l'a fait.

À la ligne 2, vous effectuez une opération d'affectation, et vous ne pouvez pas affecter un tableau de caractères à un autre tableau de caractères comme ceci. Vous devez utiliser strcpy() ou une sorte de boucle pour assigner chaque élément du tableau.

2voto

Orion Edwards Points 54939

Pour développer Réponse de Sparr

L'initialisation et l'affectation sont deux opérations distinctes qui utilisent ici le même opérateur ("=").

Pensez-y comme ça :

Imaginez qu'il existe 2 fonctions, appelées InitializeObject et AssignObject . Lorsque le compilateur voit thing = value il examine le contexte et appelle un InitializeObject si vous créez une nouvelle thing . Si vous ne l'êtes pas, il appelle plutôt AssignObject .

Normalement, cela convient car InitializeObject y AssignObject se comportent généralement de la même manière. Sauf lorsqu'il s'agit de tableaux de caractères (et quelques autres cas limites), auquel cas ils se comportent différemment. Pourquoi faire cela ? Eh bien, c'est un tout autre sujet, impliquant la pile et le tas, etc.

PS : En passant, cette façon de voir les choses vous aidera à comprendre les constructeurs de copie et d'autres éléments similaires si vous vous aventurez un jour dans le C++.

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