resueltos - funciones de cadenas de caracteres en c++
¿Cómo creo una matriz de cadenas en C? (14)
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 desde un tipo de puntero incompatible". ¿Cuál es la forma correcta de hacer esto?
edición: tengo curiosidad por qué esto debería dar una advertencia al compilador ya que si hago printf(a[1]);
, imprime correctamente "hmm".
Ack! Cuerdas constantes:
const char *strings[] = {"one","two","three"};
Si recuerdo correctamente.
Ah, y quieres usar strcpy para la asignación, no el operador =. strcpy_s es más seguro, pero no está ni en C89 ni en los estándares C99.
char arr[MAX_NUMBER_STRINGS][MAX_STRING_SIZE];
strcpy(arr[0], "blah");
Actualización: Thomas dice que strlcpy
es el camino a seguir.
Aquí tienes algunas de tus opciones:
char a1[][14] = { "blah", "hmm" };
char* a2[] = { "blah", "hmm" };
char (*a3[])[] = { &"blah", &"hmm" }; // only since you brought up the syntax -
printf(a1[0]); // prints blah
printf(a2[0]); // prints blah
printf(*a3[0]); // prints blah
La ventaja de a2 es que puedes hacer lo siguiente con literales de cadena
a2[0] = "hmm";
a2[1] = "blah";
Y para a3 puedes hacer lo siguiente:
a3[0] = &"hmm";
a3[1] = &"blah";
Para a1, tendrá que usar strcpy incluso cuando asigne literales de cadena. La razón es que a2, y a3 son matrices de punteros y puede hacer que sus elementos (es decir, punteros) apunten a cualquier almacenamiento, mientras que a1 es una matriz de ''matriz de caracteres'' y así cada elemento es una matriz que "posee" su Almacenamiento propio (lo que significa que se destruye cuando se sale del alcance): solo puedes copiar cosas en su almacenamiento.
Esto también nos lleva a la desventaja de usar a2 y a3, ya 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 sin cadena a los elementos de a2 o a3: 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 asegurarse de desasignar la memoria cuando termine.
Bah - Ya extraño a C ++;)
ps. Déjame saber si necesitas ejemplos.
En ANSI C:
char* strings[3];
strings[0] = "foo";
strings[1] = "bar";
strings[2] = "baz";
Hay varias formas de crear una matriz de cadenas en C. Si todas las cadenas van a tener la misma longitud (o al menos tienen la misma longitud máxima), simplemente declara una matriz de caracteres de 2 días y asigne según sea necesario:
char strs[NUMBER_OF_STRINGS][STRING_LENGTH+1];
...
strcpy(strs[0], aString); // where aString is either an array or pointer to char
strcpy(strs[1], "foo");
También puede agregar una lista de inicializadores:
char strs[NUMBER_OF_STRINGS][STRING_LENGTH+1] = {"foo", "bar", "bletch", ...};
Esto supone que el tamaño y la cantidad de cadenas en el inicializador coinciden con las dimensiones de su matriz. En este caso, el contenido de cada cadena literal (que en sí es una matriz de caracteres terminada 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 que tienen 5 caracteres o menos, pero 1 cadena que tiene 20 caracteres de longitud, 99 cadenas tendrán al menos 15 caracteres no utilizados; Eso es un desperdicio de espacio.
En lugar de utilizar una matriz de caracteres 2-d, puede almacenar una matriz de punteros de 1 días para char:
char *strs[NUMBER_OF_STRINGS];
Tenga en cuenta que en este caso, solo ha asignado memoria para contener los punteros a las cadenas; la memoria de las propias cadenas debe asignarse en otro lugar (ya sea como matrices estáticas o utilizando malloc () o calloc ()). Puede usar la lista de inicializadores como en el ejemplo anterior:
char *strs[NUMBER_OF_STRINGS] = {"foo", "bar", "bletch", ...};
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; Puedes reasignar el puntero, así:
strs[i] = "bar";
strs[i] = "foo";
Pero es posible que no puedas cambiar el contenido de la cadena; es decir,
strs[i] = "bar";
strcpy(strs[i], "foo");
no puede ser permitido
Puede usar malloc () para asignar dinámicamente el búfer para cada cadena y copiarlo a ese búfer:
strs[i] = malloc(strlen("foo") + 1);
strcpy(strs[i], "foo");
Por cierto,
char (*a[2])[14];
Declara a como una matriz de 2 elementos de punteros a matrices de 14 elementos de char.
Los literales de cadena son const char *
s.
Y su uso de paréntesis es extraño. Probablemente te refieres
const char *a[2] = {"blah", "hmm"};
que declara una matriz de dos punteros a caracteres constantes, y los inicializa para apuntar a dos constantes de cadena codificadas.
Me faltaba de alguna manera una matriz más dinámica de cadenas, donde la cantidad de cadenas podía variar dependiendo de la selección del tiempo de ejecución, pero de lo contrario las cadenas deberían ser fijas.
He terminado de codificar código como este:
#define INIT_STRING_ARRAY(...) /
{ /
char* args[] = __VA_ARGS__; /
ev = args; /
count = _countof(args); /
}
void InitEnumIfAny(String& key, CMFCPropertyGridProperty* item)
{
USES_CONVERSION;
char** ev = nullptr;
int count = 0;
if( key.Compare("horizontal_alignment") )
INIT_STRING_ARRAY( { "top", "bottom" } )
if (key.Compare("boolean"))
INIT_STRING_ARRAY( { "yes", "no" } )
if( ev == nullptr )
return;
for( int i = 0; i < count; i++)
item->AddOption(A2T(ev[i]));
item->AllowEdit(FALSE);
}
char** ev
toma el puntero a las cadenas de la matriz, y el conteo recoge la cantidad de cadenas usando la función _countof
. (Similar a sizeof(arr) / sizeof(arr[0])
).
Y hay una conversión adicional de Ansi a Unicode utilizando la macro A2T
, pero eso podría ser opcional para su caso.
O puede declarar un tipo de estructura, que contiene un conjunto de caracteres (1 cadena), ellos crean una matriz de las estructuras y, por lo tanto, una matriz de elementos múltiples
typedef struct name
{
char name[100]; // 100 character array
}name;
main()
{
name yourString[10]; // 10 strings
printf("Enter something/n:);
scanf("%s",yourString[0].name);
scanf("%s",yourString[1].name);
// maybe put a for loop and a few print ststements to simplify code
// this is just for example
}
Una de las ventajas de esto sobre cualquier otro método es que le permite escanear directamente en la cadena sin tener que usar strcpy
;
Si las cuerdas son estáticas, mejor que mejor con:
const char *my_array[] = {"eenie","meenie","miney"};
Si bien no es parte de 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 utilizan menos gastos generales que la creación dinámica de una matriz de cadenas.
Por ejemplo, en pequeños proyectos de microcontrolador, esta sintaxis utiliza la memoria del programa en lugar de (generalmente) la memoria RAM más valiosa. AVR-C es un entorno de ejemplo que admite esta sintaxis, pero también la mayoría de los otros.
Si no desea cambiar las cadenas, simplemente puede hacer
const char *a[2];
a[0] = "blah";
a[1] = "hmm";
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
char a[2][14];
strcpy(a[0], "blah");
strcpy(a[1], "hmm");
Esto asignará dos matrices consecutivas de 14 caracteres cada una, después de lo cual se copiará en ellas el contenido de las cadenas estáticas.
Si no desea realizar un seguimiento de la cantidad de cadenas en la matriz y desea iterar sobre ellas, simplemente agregue una cadena NULA al final:
char *strings[]={ "one", "two", "three", NULL };
int i=0;
while(strings[i]) {
printf("%s/n", strings[i]);
//do something
i++;
};
Una buena manera es definir una cadena de uno mismo.
#include <stdio.h>
typedef char string[]
int main() {
string test = "string";
return 0;
}
Es realmente tan simple.
hola puedes probar este bramido
char arr[nb_of_string][max_string_length];
strcpy(arr[0], "word");
un buen ejemplo de uso de una serie de cadenas en c si lo desea
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]){
int i, j, k;
// to set you array
//const arr[nb_of_string][max_string_length]
char array[3][100];
char temp[100];
char word[100];
for (i = 0; i < 3; i++){
printf("type word %d : ",i+1);
scanf("%s", word);
strcpy(array[i], word);
}
for (k=0; k<3-1; k++){
for (i=0; i<3-1; i++)
{
for (j=0; j<strlen(array[i]); j++)
{
// if a letter ascii code is bigger we swap values
if (array[i][j] > array[i+1][j])
{
strcpy(temp, array[i+1]);
strcpy(array[i+1], array[i]);
strcpy(array[i], temp);
j = 999;
}
// if a letter ascii code is smaller we stop
if (array[i][j] < array[i+1][j])
{
j = 999;
}
}
}
}
for (i=0; i<3; i++)
{
printf("%s/n",array[i]);
}
return 0;
}
char name[10][10]
int i,j,n;//here "n" is number of enteries
printf("/nEnter size of array = ");
scanf("%d",&n);
for(i=0;i<n;i++)
{
for(j=0;j<1;j++)
{
printf("/nEnter name = ");
scanf("%s",&name[i]);
}
}
//printing the data
for(i=0;i<n;i++)
{
for(j=0;j<1;j++)
{
printf("%d/t|/t%s/t|/t%s",rollno[i][j],name[i],sex[i]);
}
printf("/n");
}
Aquí prueba esto!