[C con Clase] Dudas con realloc

Martin Strahd xaninverno en gmail.com
Mie Feb 9 22:32:35 CET 2011


Buenas

Estoy aprendiendo respecto de la asignación dinamica de memoria en C y me
encuentro con algunas dificultades a la hora de solucionar un ejercicio del
manual que estoy siguiendo. El ejercicio en sí pide construir un diccionario
inglés-español y, para ello, creo que la solución consiste en crear un array
de punteros a punteros. El enunciado del problema es el siguiente:

*Realizar un programa que permita utilizar el terminal como un diccionario
Inglés-Español, esto es, al introducir una palabra
en inglés, se escribirá la correspondiente palabra en español. El númerp de
parejas de palabras es variable, pero limitado a
un máximo de 100. La longitud máxima de cada palabra será de 40 caracteres.
Por ejemplo, introducimos las siguientes parejas
de palabras:

book    libro
green   verde
mouse   ratón

Una vez finalizada la introducción de la lista, pasamos al modo traducción,
de forma que si tecleamos green, la respuesta ha
de ser verde. Si la palabra no se encuentra se emitirá un mensaje que lo
indique.

El programa constará al menos de dos funciones:

a) CrearDiccionario. Esta función creará el diccionario
b) Traducir. Esta función realizará la labor de traducción

*La solución que se me ha ocurrido es crear dos arrays de punteros a
punteros tipo char, de modo que cada pareja de palabras se almacenen en la
misma posición, es decir, door se almacenaría en el puntero ping[0] y puerta
en el pesp [0] y así sucesivamente. Como el ejercicio pide una función
específica para crear el diccionario, creo que hay que pasar esos arrays por
referencia, ya que variarán durante la creación del mismo. Posteo el código
completo para explicarme mejor:

#include <stdio.h>
#include <stdlib.h>

/**** Prototipos de las funciones ****/
int crearDiccionario (char ***, char ***);     /* Recibe dos arrays de
punteros (el de palabras inglesas y el de palabras españolas) y devuelve el
número de elementos de ese array */
void traducir (char**, char **, char *);     /* Recibe los dos arrays de
punteros y una cadena. Buscará en el array 1 la cadena buscada y si lo
encuentra devolverá la pareja localizada en el array 2 */

void main(void)
{
    int tam;                        /* En esta variable se almacenará el
tamaño del array de punteros (es decir, el número de parejas del
diccionario) */
    char **ping = NULL, **pesp = NULL;            /* Arrays de punteros a
punteros char. Uno es el de palabras en ingles y el otro en español */
    char palabra[40];                               /* En esta cadena se
almacena la palabra a buscar */
    char *q;                                        /* Almacen para el
retorno de gets */

    *tam = crearDiccionario(&ping, &pesp)*; /* Tras esta función sabremos el
número de parejas creadas y sus respectivas direcciones */
                                          /* Los punteros se pasan por
referencia (&) ya que su valor cambiará durante la ejecución de la función y
nos interesa conservar esos valores */

    /** Una vez creado el diccionario se consulta sobre él **/

   printf ("\n** Consulta sobre el diccionario **");
   printf ("\n***********************************");
   printf ("\nEscribe una palabra para buscar en el diccionario. Pulsa
<Enter> o EOF para salir de la consulta");
   printf ("\nPalabra?: ");
   q = gets(palabra);
   while (!q && palabra[0] != '\0')         /* Mientras haya un valor válido
mayor de 0 el bucle se ejecutará */
   {
       traducir (ping, pesp, palabra);      /* Se le dan los punteros a
punteros de cadenas y la palabra a buscar */
       printf ("Escribe otra palabra para buscar (Pulsa <Enter> o EOF para
salir): ");
       q = gets(palabra);
   }
}

int crearDiccionario (char ***ing, char ***esp)
/** Esta función recibe dos punteros a arrays de punteros de tipo char y
devolverá la dimensión de ambos
Se pasan ambos arrays por referencia, de ahí los 3 *.
El primer array de punteros es el de palabras inglesas, el segundo el de
palabras españolas,
ambos arrays crecen simultáneamente, por eso sólo es necesario un int para
la dimensión **/
{
    int tam = 0;         /* En esta variable se almacenará el incremento de
las dimensiones del array */
    char palai[40], palae[40];  /* Para almacenar los valores temporales de
las palabras del diccionario */

    printf("\nIntroduce parejas de palabras, para finalizar introduce cadena
vacia en ambas palabras");
    do
    {
        // Primero se comprueba que hay una entrada valida, es decir, hay
valores distintos de 0 en palai y palae
        printf ("\nIngles: ");
        gets(palai);
        printf ("\nEspañol: ");
        gets(palae);
        if (palae[0] != 0 && palai[0] != 0)     /* Si ambas palabras son
distintas de 0 se ejecuta este codig */
        {
            // Una vez tenemos valores validos comenzamos el trasvase a
nuestro array
            tam++;          /* Primero incrementamos el contador */

           /* Estas dos líneas las pongo por si acaso, aunque el error se
sigue produciendo */
           ing = NULL;
           esp = NULL;

            */*** Reservamos memoria para ambos arrays de punteros ***/
            ing = (char**)realloc(ing, tam * sizeof (char*));
            esp = (char**)realloc(esp, tam * sizeof (char*));
*

            /** Ahora se reserva memoria para cada uno de los elementos **/
            ing[tam-1] = NULL;
            ing[tam-1] = (char*)realloc(ing[tam-1],
sizeof(char)*(strlen(palai)+1));
            esp[tam-1] = NULL;
            esp[tam-1] = (char*)realloc(esp[tam-1],
sizeof(char)*(strlen(palae)+1));
        }
    }
    while (palai[0] != 0 && palae[0] != 0);

    return (tam);
}

Lo que ocurre es que al compilar esto, me salta un mensaje indicando que los
punteros son incompatibles. Creo que la clave radica en esos tres asteriscos
que he puesto, pero no se me ocurre otra forma de pasar unos punteros que se
vayan ajustando al tamaño del array según va creciendo, ya que si los paso
por valor, al finalizar la función crearDiccionario se destruirán y el
código no habrá valido de nada. ¿Alguna sugerencia?

Gracias por la ayuda
Xan.


-- 
Una vez le preguntaron al Buda que es lo que a él más le sorprendía de la
humanidad. El Buda respondió: "Los hombres, que pierden la salud para juntar
dinero, y luego pierden el dinero para recuperarla y que por pensar
ansiosamente en el futuro olvidan el presente de tal forma, que acaban por
no vivir ni el presente ni el futuro. Viven como si nunca fuesen a morir, y
mueren como si nunca hubiesen vivido".
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20110209/223733b0/attachment.html>


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