[C con Clase] Array de cadenas de caracteres y p aso de parám etros en C.

srd4121 en njit.edu srd4121 en njit.edu
Jue Nov 27 22:59:41 CET 2008


Hola gmh,

Quoting gmh2000 <helder1986 en gmail.com>:

> /* Hola. No sé si estoy repitiendo el envío, pero es que no veo el
> mensaje enviado en el foro. De todas formas he conseguido que la cosa
> ande, aunque con la sulución que no me gusta (la de abajo del todo).
> Así, que este mensaje es más bien para aprender mejores formas. 
> 
> /* He intentado de varias maneras trabajar con arrays de cadenas en C y
> la cosa no funciona bien. Escribo nombres de funciones y variables para
> que pueda servir para todo el mundo en futuras ocasiones. Concreto: */
> 

Veamos las inquietudes.

> /* Declaración. También probé con [64][11]; */
> char array_cadenas [][11];
> 

Esto es incorrecto. Debes indicar todos los tamaños en una declaración. La
excepción es cuando tengas declaración e inicialización; entonces, el compilador
puede averiguar la cantidad total de elementos y de bytes de memoria.

> for(i = 0; i <= numero_de_cadenas; i++)

Esto no es correcto. Fíjate que la variable 'i', que actúa de índice, empieza
por 0 (cero). Por lo tanto, el valor del último elemento será:
'numero_de_cadenas-1'. También puedes expresar el bucle 'for' así:

for( i=0; i < numero_de_cadenas; i++ )

> {
> array_cadenas[i][0] = cadena_x; /* ¿esta asignación es correcta? */

No. Cuando tienes dudas acerca de las operaciones, siempre ten presente los
tipos de datos y los tipos de los datos resultantes de tales operaciones.
Recuerda que C y C++ son lenguajes fuertemente tipificados; es decir, los tipos
de datos siempre priman.

En este caso, estás asignando una cadena de tipo 'char []' a un 'char'. Veamos
los tipos de datos:

- array_cadenas       ==> char [64][11]
- array_cadenas[i]    ==> (char [64][11]) [] i ==> char [11]
- array_cadenas[i][0] ==> ((char [64][11]) [] i) [] 0 ==> (char [11]) [] 0 ==> char
- cadena_x ==> char [11]

Al final, tenemos la asignación entre datos de los siguientes tipos:

<char> = <char [11]>

Como puedes ver, los tipos no coinciden, ni tampoco existe una regla semántica
que convierta un tipo en otro para que esta asignación se realice correctamente.

Si quieres asignar cadenas de caracteres, tendrás que asignar su contenido.
Además tienes un array de cadenas de caracteres y por tanto tienes una tabla de
caracteres; o sea, un array 2D. Esto implica dos bucles 'for' anidados: uno para
el array de 64 cadenas y otro para la cantidad de caracteres de cada cadena - 11.

> }
> 
> /* Siguiente función mostrará las cadenas introducidas por pantalla */
> /* Diría que la función muestra sólo el primer caracter de la cadena
> correspondiente. También probé con &array_cadenas[j][0] */
> for(j = 0; j <= numero_de_cadenas; j++)

Nuevamente, el último índice es uno menos de la cantidad total. Puedes usar el
operador < en lugar de <=.

> {
> funcionMuestraTexto(array_cadenas[j][0]);

Esto implica que esta función mostrará una sola cadena de caracteres (texto).
Por lo tanto, debes pasar un array de tipo 'char'. Aplicando lo que ya venimos
diciendo, comprueba los tipos de los datos que estás manipulando. El esquema
viene a ser el siguiente para 'array_cadenas[j][0]':

(<char [64][11]> [] j) [0] ==> <char [11]> [0] ==> char

Como acabamos de comprobar, estás pasando un 'char' - un solo carácter - a tu
función, la cual espera una cadena de caracteres. Como los tipos no coinciden y
no existe una posible conversión de un tipo al otro, se producirá un error.

> }
> 
> /* De esta forma compila con ciertos warnings, como por ejemplo:
> assignment makes integer from pointer without a cast. Y el programa
> (pidgin) muestra las cadenas en "chino". Así que supongo que algo haré
> mal. */
> 

Esto es el resultado de varios errores acumulados. Me sorprende que el programa
se ejecute sin producir un error indicado por el sistema operativo.

> 
> /* ---------------------------------------------------------*/
> /* También lo intenté trabajando con punteros */
> char* array_de_cadenas[64];
> array_de_cadenas[i] = cadena_x;
> 

Esto es sintáctica y semánticamente correcto, pero quizá no sea lógico. Ten
presente que no estás copiando las cadenas de caracteres sino que estás copiando
los punteros. Esto se llama una "copia de poca o baja profundidad". Esto implica
que cualquier cambio usando un puntero implícitamente aparece en el otro. Por
ejemplo,

array_de_caracteres[0][0] = 'H';
array_de_caracteres[0][1] = 'o';
array_de_caracteres[0][2] = 'l';
array_de_caracteres[0][3] = 'a';
array_de_caracteres[0][4] = '\0';

cadena_x[0] = 'h';

cout << array_de_caracteres[0];

Aparecerá en pantalla:
hola

Esto es debido a la copia de baja profundidad.


Espero haber aclarado las dudas.

Steven





Más información sobre la lista de distribución Cconclase