2010-08-31 5 views
3

Ceci est lié à mon précédent posterreur C2440: '=': ne peut pas convertir de 'char [5]' à 'char [20]'

Wher J'ai créé un struct:

struct buffer 
{ 
    char ProjectName[20]; 
     char ProjectID[20]; 
}; 

maintenant, alors que je suis en train d'attribuer des valeurs à elle:

buffer buf; 
buf.ProjectID = "3174"; 
buf.ProjectName = "NDS"; 

Je reçois cette erreur:

error C2440: '=' : cannot convert from 'char [5]' to 'char [20]' 

et de résoudre ce que j'ai essayé de diminuer la taille de la structure comme ci-dessous (ne doit pas être la façon de le faire):

struct buffer 
{ 

    char ProjectName[4]; 
    char ProjectID[5]; 
}; 

et obtenir error C2106: '=' : left operand must be l-value

+0

Utilisez std :: String plutôt que des tableaux char. –

Répondre

7

Vous devez copier la chaîne dans la tableau:

strcpy(buf.ProjectName, "3174"); 

Soyez prudent avec la longueur des chaînes sont copiées dans les tableaux

4

Vous ne pouvez pas attribuer de chaînes comme celle-ci en C++. Vous devez utiliser la fonction telle que strcpy pour copier la chaîne. Ou mieux encore, utilisez la classe std::string

+0

Pourriez-vous fournir un code snipper s'il vous plaît – Simsons

+0

@Subhen Voir la réponse par @jab pour un exemple d'utilisation de strcpy() –

3

C'est normal, vous ne pouvez pas vraiment attribuer de valeurs aux tables de caractères de cette façon (il existe de nombreuses solutions différentes, sprintf ou strcpy par exemple). Mais c'est un problème C, pas C++. Puisque vous codez en C++, vous devriez utiliser std :: string pour gérer vos chaînes (et la méthode c_str() si vous avez besoin de ces chaînes converties en tables char).

3

Regardons au premier cas:

buffer buf; 
buf.ProjectID = "3174"; 
buf.ProjectName = "NDS"; 

$2.13.4/1 - "An ordinary string literal has type “array of n const char” and static storage duration (3.7)"

Le type de "3174" est char const [5] et le type de "NDS" est char const [4]. Tout en essayant de tenter l'affectation à 'buf.ProjectID', le compilateur doit essentiellement convertir de 'char const [5]' à 'char const [20]'. Cette conversion n'est pas autorisée par les règles C++. En fait, un message d'erreur plus approprié est lancé lors de votre prochaine tentative.

$8.3.4/5 - '[Note: conversions affecting lvalues of array type are described in 4.2. Objects of array types cannot be modified, see 3.10. ]".

En d'autres termes, cela signifie que le nom d'un tableau est lvalue non modifiable (qui est ce que le 2ème message compilateur dit).

$5.17- "There are several assignment operators, all of which group right-to-left. All require a modifiable lvalue as their left operand, and the type of an assignment expression is that of its left operand."

Voici donc le résumé:

Pour l'expression d'affectation à un travail, le côté gauche doit être une expression lvalue modifiable. Cependant, un tableau est une expression Lvalue non modifiable. Par conséquent, il ne peut pas être affecté à.

+2

L'affiche ne comprendra pas que ...: - /. –

+0

@Tony: Merci pour vos commentaires. Ont légèrement élaboré plus loin – Chubsdad

1

Je suis désolé de dire que C++ est un peu intuitif ici.Vous pouvez dire:

char name[10] = "abcd"; 

et, compte tenu de votre définition ci-dessus:

buffer buf = { "NDS", "3174" }; 

Ce dernier repose sur une à une correspondance entre les champs dans la structure et les valeurs de la liste, donc je J'ai dû inverser l'ordre utilisé dans vos missions.

Mais, vous ne pouvez pas faire votre

buf.ProjectName = "abcde"; 

Qu'est-ce que les demandes ont effectivement en C++ est que buf.ProjectName être chargé avec un pointeur vers la mémoire contenant les données de caractères « ABCDE ». Vous ne pouvez pas faire cela, car ProjectName lui-même est un autre tampon pour les données de caractères, et pas de pointeur vers les données de caractères.

Donc, quand vous avez une source et la zone de destination contenant des chaînes terminées par NUL (Google ASCIIZ si nécessaire), vous devez utiliser une fonction de support pour copier l'un à l'autre:

strcpy(buf.ProjectName, "name"); 

Si ProjectName de dimension est trop petite, alors votre chaîne peut écraser la mémoire que le compilateur n'a pas réservée à ProjectName, provoquant probablement un crash ou une sortie erronée. Vous pouvez protéger contre cela - si les tailles relatives des chaînes ne sont pas manifestement correctes - en utilisant strncpy(buf.ProjectName, "name", sizeof buf.ProjectName). Malheureusement, cela signifie que buf.ProjectName peut ne pas contenir toute la valeur attendue, ce qui rend l'utilisation douteuse.

C++ améliore cette façon de gérer les données textuelles - héritées de C - avec la classe std :: string. Vous pouvez simplement faire ceci:

#include <string> 
struct Buffer 
{ 
    std::string project_name_; 
    std::string project_id_; 
}; 
Buffer b; 
b.project_name_ = "abcde"; // works with string literals. 
b.project_id_ = b.project_name_; // can copy from std::string to std::string 
Questions connexes