2010-08-13 12 views
7

¿Por qué el siguiente código es ilegal?literal de cadena en c

typedef struct{ 
    char a[6]; 
} point; 

int main() 
{ 
    point p; 
    p.a = "onetwo"; 
} 

¿Tiene algo que ver con el tamaño del literal? ¿o es ilegal asignar un literal de cadena a una matriz de caracteres una vez que se ha declarado?

+0

posible duplicado de [Asignación de cadenas a arreglos de caracteres] (http://stackoverflow.com/questions/579734/assigning-strings-to-arrays-of-characters) –

+0

no es un duplicado, porque esta es una estructura que contiene una matriz de caracteres, que es sutilmente diferente a simplemente un array de caracteres regulares, he explicado en mi respuesta. – dreamlax

Respuesta

11

No tiene nada que ver con el tamaño. No se puede asignar un literal de cadena a una matriz char después de su creación; solo puede usarla en el momento de la definición.

Al hacer

char a[] = "something"; 

se crea una matriz de tamaño suficiente (incluyendo el terminador nulo) y copia la cadena a la matriz. No es una buena práctica especificar el tamaño del conjunto cuando lo inicializa con un literal de cadena; es posible que no tenga en cuenta el carácter nulo.

Al hacer

char a[10]; 
a = "something"; 

que está tratando de asignar a la dirección de la matriz, lo cual es ilegal.

EDITAR: como se menciona en otras respuestas, puede hacer una strcpy/strncpy, pero asegúrese de que la matriz se haya inicializado con la longitud requerida.

strcpy(p.a, "12345");//give space for the \0 
6

Nunca se puede asignar a las matrices después de que se hayan creado; esto es igualmente ilegal:

int foo[4]; 
int bar[4]; 
foo = bar; 

Debe usar punteros o asignar a un índice de la matriz; esto es legal:

p.a[0] = 'o'; 

Si desea dejar una matriz en la estructura, se puede utilizar una función como strcpy:

strncpy(p.a, "onetwo", 6); 

(tenga en cuenta que la matriz de caracteres tiene que ser lo suficientemente grande para mantener el nulo terminador también, así que es probable que desee para que sea char a[7] y cambiar el último argumento de strncpy a 7)

+1

Creo que debería ser halagado de que cada respuesta editado en mi 'solución strcpy' –

+0

Aquí, tienen un +1. Me gustaría +2 si pudiera, pero me parece un poco extraño que nadie haya notado que esta es una 'struct' que contiene una matriz, no solo una matriz simple. – dreamlax

+0

Por supuesto, "strncpy" viene con sus propios problemas, a diferencia de la mayoría de las otras funciones de "n". –

6

las matrices son non modifiable lvalues. Entonces no puedes asignarles. El lado izquierdo del operador de asignación debe ser modifiable lvalue.

Sin embargo, puede inicializar una matriz cuando está definida.

Por ejemplo:

char a[] = "Hello World" ;// this is legal 
char a[]={'H','e','l','l','o',' ','W','o','r','l','d','\0'};//this is also legal 

//but 

char a[20]; 
a = "Hello World" ;// is illegal 

Sin embargo puede utilizar strncpy(a, "Hello World",20);

+2

Sería más claro si se ha utilizado el término correcto 'inicializar' en lugar de 'asignar' cuando una matriz se 'define' (en lugar de 'declarado'). –

+2

@Jonathan: Sí, eres pedantemente correcto. ¡Fijo! :) –

1

Tenga en cuenta que con el fin de almacenar la cadena "onetwo" en su conjunto, tiene que ser de longitud [7] y no como está escrito en la pregunta. El carácter adicional es para almacenar el terminador '\ 0'.

3

Como otras respuestas ya han señalado, solo puede inicializar una matriz de caracteres con una cadena literal, no puede asignar una cadena literal a una matriz de caracteres. Sin embargo, las estructuras (incluso aquellas que contienen matrices de caracteres) son otra olla de pescado.

yo no recomendaría hacer esto en un programa real, pero esto demuestra que aunque los tipos de matrices no se pueden asignar a, estructuras que contienen los tipos de matriz pueden ser.

typedef struct 
{ 
    char value[100]; 
} string; 

int main() 
{ 
    string a = {"hello"}; 
    a = (string){"another string!"}; // overwrite value with a new string 
    puts(a.value); 

    string b = {"a NEW string"}; 
    b = a; // override with the value of another "string" struct 
    puts(b.value); // prints "another string!" again 
} 

Así, en su original ejemplo, el siguiente código debe compilarse bien:

typedef struct{ 
    char a[6]; 
} point; 

int main() 
{ 
    point p; 

    // note that only 5 characters + 1 for '\0' will fit in a char[6] array. 
    p = (point){"onetw"}; 
} 
+0

1 para los 'ejemplos struct', pero en cuenta que estos literales compuestos son una adición C99. (Lo mismo ocurre con el comentario de estilo '//'). – schot

1

Sin strcpy o C99 del compund literal que se necesita. El ejemplo de la pura ANSI C:

typedef struct{ 
    char a[6]; 
} point; 

int main() 
{ 
    point p; 
    *(point*)p.a = *(point*)"onetwo"; 
    fwrite(p.a,6,1,stdout);fflush(stdout); 
    return 0; 
} 
Cuestiones relacionadas