Asignar cadenas a matrices de caracteres
Estoy un poco sorprendido por lo siguiente.
Ejemplo 1:
char s[100] = "abcd"; // declare and initialize - WORKS
Ejemplo 2:
char s[100]; // declare
s = "hello"; // initalize - DOESN'T WORK ('lvalue required' error)
Me pregunto por qué el segundo enfoque no funciona. ¿Parece natural que así sea (funciona con otros tipos de datos)? ¿Alguien podría explicarme la lógica detrás de esto?
Al inicializar una matriz, C le permite llenarla con valores. Entonces
char s[100] = "abcd";
es básicamente lo mismo que
int s[3] = { 1, 2, 3 };
pero no te permite realizar la tarea ya que s
es una matriz y no un puntero libre. El significado de
s = "abcd"
es asignar el valor del puntero abcd
a s
pero no puede cambiarlo s
ya que entonces nada apuntará a la matriz.
Esto puede funcionar y funciona si s
es un char*
puntero que puede señalar cualquier cosa.
Si desea copiar la cadena, use simplemente strcpy
.
No existe una "cadena" en C. En C, las cadenas son una matriz unidimensional de char
, terminada en un carácter nulo \0
. Como no puedes asignar matrices en C, tampoco puedes asignar cadenas. El "hola" literal es azúcar sintáctico paraconst char x[] = {'h','e','l','l','o','\0'};
La forma correcta sería:
char s[100];
strncpy(s, "hello", 100);
o mejor aún:
#define STRMAX 100
char s[STRMAX];
size_t len;
len = strncpy(s, "hello", STRMAX);
La inicialización y la asignación son dos operaciones distintas que aquí utilizan el mismo operador ("=").
1 char s[100];
2 s = "hello";
En el ejemplo que proporcionó, s en realidad se inicializa en la línea 1, no en la línea 2. Aunque no le asignó un valor explícitamente en este punto, el compilador lo hizo.
En la línea 2, estás realizando una operación de asignación y no puedes asignar una matriz de caracteres a otra matriz de caracteres como esta. Tendrás que usar strcpy()
algún tipo de bucle para asignar cada elemento de la matriz.
Para ampliar la respuesta de Sparr
La inicialización y la asignación son dos operaciones distintas que aquí utilizan el mismo operador ("=").
Piensa en esto, de esta manera:
Imagine que hay 2 funciones, llamadas InitializeObject
y AssignObject
. Cuando el compilador ve thing = value
, mira el contexto y llama a uno InitializeObject
si estás creando uno nuevo thing
. Si no es así, llama AssignObject
.
Normalmente esto está bien InitializeObject
y AssignObject
suele comportarse de la misma manera. Excepto cuando se trata de matrices de caracteres (y algunos otros casos extremos), en cuyo caso se comportan de manera diferente. ¿Por qué hacer esto? Bueno, esa es otra publicación que involucra la pila versus el montón y así sucesivamente.
PD: aparte, pensarlo de esta manera también te ayudará a comprender los constructores de copias y otras cosas similares si alguna vez te aventuras en C++.