Estoy tratando de crear una matriz de cadenas en C. Si uso este código:
char (*a[2])[14];
a[0]="blah";
a[1]="hmm";
gcc me da "advertencia: asignación de tipo de puntero incompatible". ¿Cuál es la forma correcta de hacer esto?
editar: Tengo curiosidad por qué esto debería dar una advertencia del compilador ya que si lo hago printf(a[1]);
, imprime correctamente "hmm".
char (*a[2])[14]
es una matriz de dos punteros a una matriz de 14 caracteres.char (*a[2])[14]
- comience ena
, mueva a la derecha: "matriz de dos", mueva a la izquierda: "puntero a", soporte completo, así que lea a la derecha: "conjunto de forteen", lea a la izquierda: "char" ... Júntelo y tenemos "un conjunto de dos punteros a conjuntos de caracteres forteen"char *str
lugar de hacerlochar* str
. Viniendo de un fondo de Delphi / Pascal, estaba muy acostumbrado a esto último hasta que encontré tipos más complejos. La primera forma todavía me parece fea, pero hace que la notación de tipo sea más consistente (IMO).Respuestas:
Si no desea cambiar las cadenas, simplemente puede hacer
Cuando lo haga así, asignará una matriz de dos punteros a
const char
. Estos punteros se establecerán en las direcciones de las cadenas estáticas"blah"
y"hmm"
.Si desea poder cambiar el contenido real de la cadena, debe hacer algo como
Esto asignará dos matrices consecutivas de 14
char
s cada una, después de lo cual el contenido de las cadenas estáticas se copiará en ellas.fuente
Hay varias formas de crear una matriz de cadenas en C. Si todas las cadenas van a tener la misma longitud (o al menos tendrán la misma longitud máxima), simplemente declare una matriz 2D de caracteres y asigne según sea necesario:
También puede agregar una lista de inicializadores:
Esto supone que el tamaño y el número de cadenas en el inicializador coinciden con las dimensiones de su matriz. En este caso, el contenido de cada literal de cadena (que en sí mismo es una matriz de caracteres terminados en cero) se copia en la memoria asignada a las cadenas. El problema con este enfoque es la posibilidad de fragmentación interna; si tiene 99 cadenas de 5 caracteres o menos, pero 1 cadena de 20 caracteres de longitud, 99 cadenas tendrán al menos 15 caracteres no utilizados; Eso es una pérdida de espacio.
En lugar de usar una matriz 2-d de char, puede almacenar una matriz 1-d de punteros para char:
Tenga en cuenta que en este caso, solo ha asignado memoria para mantener los punteros a las cadenas; la memoria para las propias cadenas debe asignarse a otra parte (ya sea como matrices estáticas o usando
malloc()
ocalloc()
). Puede usar la lista de inicializadores como en el ejemplo anterior:En lugar de copiar el contenido de las constantes de cadena, simplemente está almacenando los punteros a ellas. Tenga en cuenta que las constantes de cadena pueden no ser grabables; puede reasignar el puntero, así:
Pero es posible que no pueda cambiar el contenido de la cadena; es decir,
puede no estar permitido
Puede usar
malloc()
para asignar dinámicamente el búfer para cada cadena y copiar a ese búfer:Por cierto,
Declara a como una matriz de punteros de 2 elementos a matrices de 14 elementos de char.
fuente
malloc
llamada.T [N]
se convierte en una expresión de tipoT *
, y el valor de la expresión es la dirección del primer elemento. Entonces, si escribióstr = "foo"
, intentaría asignar la dirección del primer carácter"foo"
a la matrizstr
, lo que no funciona. Vea esta respuesta para más detalles.char *strs[NUMBER_OF_STRINGS] = {0};
Esto ayuda a prevenir futuros problemas inicializandostrs
aNULL
. Mucha gente lee esta publicación cuando Google busca en una variedad de cadenas en C.Ack! Cuerdas constantes:
Si recuerdo correctamente.
Ah, y desea utilizar strcpy para la asignación, no el operador =.strcpy_s es más seguro, pero no está en los estándares C89 ni C99.
Actualización: Thomas dice que
strlcpy
es el camino a seguir.fuente
Aquí tienes algunas de tus opciones:
La ventaja de esto
a2
es que puede hacer lo siguiente con literales de cadenaY para
a3
usted puede hacer lo siguiente:Para
a1
que tendrá que utilizarstrcpy()
(mejor aúnstrncpy()
), incluso cuando la asignación de los literales de cadena. La razón es esoa2
, ya3
son conjuntos de punteros y puede hacer que sus elementos (es decir, punteros) apunten a cualquier almacenamiento, mientras quea1
es un conjunto de 'conjunto de caracteres' y, por lo tanto, cada elemento es un conjunto que "posee" su propio almacenamiento ( lo que significa que se destruye cuando sale del alcance): solo puede copiar cosas en su almacenamiento.Esto también nos lleva a la desventaja de usar
a2
ya3
, dado que apuntan al almacenamiento estático (donde se almacenan los literales de cadena) cuyo contenido no se puede cambiar de manera confiable (es decir, comportamiento indefinido), si desea asignar literales no de cadena al elementos dea2
oa3
- primero tendrá que asignar dinámicamente suficiente memoria y luego hacer que sus elementos apunten a esta memoria, y luego copiar los caracteres en ella - y luego debe asegurarse de desasignar la memoria cuando haya terminado.Bah: ya extraño C ++;)
PD Avísame si necesitas ejemplos.
fuente
O puede declarar un tipo de estructura, que contiene un conjunto de caracteres (1 cadena), crear una matriz de estructuras y, por lo tanto, una matriz de elementos múltiples
Una de las ventajas de esto sobre cualquier otro método es que le permite escanear directamente en la cadena sin tener que usarla
strcpy
;fuente
En ANSI C:
fuente
char* foo, bar;
¿de qué tipo esbar
?Si las cadenas son estáticas, es mejor que:
Si bien no forma parte del ANSI C básico, es probable que su entorno admita la sintaxis. Estas cadenas son inmutables (solo lectura) y, por lo tanto, en muchos entornos usan menos sobrecarga que construir dinámicamente una matriz de cadenas.
Por ejemplo, en pequeños proyectos de microcontroladores, esta sintaxis usa memoria de programa en lugar de (usualmente) memoria RAM más preciada. AVR-C es un entorno de ejemplo que admite esta sintaxis, pero también lo hacen la mayoría de los otros.
fuente
Si no desea realizar un seguimiento del número de cadenas en la matriz y desea iterar sobre ellas, simplemente agregue una cadena NULL al final:
fuente
Los literales de cadena son
const char *
s.Y su uso de paréntesis es extraño. Probablemente quieras decir
que declara una matriz de dos punteros a caracteres constantes, y los inicializa para apuntar a dos constantes de cadena codificadas.
fuente
Su código está creando una matriz de punteros de función. Tratar
o
en lugar.
Ver wikilibros a matrices y punteros
fuente
hola puedes probar esto a continuación:
un buen ejemplo de uso, matriz de cadenas en c si lo desea
fuente
Aquí intenta esto !!!
fuente
Me faltaba de alguna manera una matriz más dinámica de cadenas, donde la cantidad de cadenas podría variar dependiendo de la selección del tiempo de ejecución, pero de lo contrario las cadenas deberían ser reparadas.
Terminé codificando fragmentos de código como este:
char** ev
recoge el puntero a las cadenas de matriz, y el conteo recoge la cantidad de cadenas usando la_countof
función. (Similar asizeof(arr) / sizeof(arr[0])
)Y hay una conversión adicional de Ansi a unicode usando
A2T
macro, pero eso podría ser opcional para su caso.fuente
Una buena manera es definir una cadena usted mismo.
Es realmente así de simple.
fuente
;
, y ¿cómo crea esto una serie de cadenas ?