[C con Clase] Conversión inválida de char a char. Estructuras de datos. ¿Qué pasa?

Programante programante en gmail.com
Mar Oct 2 20:18:06 CEST 2007


Ismael Ramón escribió:
> Hola de nuevo, primero gracias por responder tan rápido a mi duda 
> anterior. Esta vez hice una función (que se supone que compara el 
> nombre introducido por el usuario con los de la estructura para hallar 
> el número de teléfono asociado) para el primer ejercicio de 
> estructuras del curso, y quisiera saber qué falla en ella que el 
> compilador no ejecuta el programa e indica que estoy realizando una 
> conversión inválida de `char*' a `char' en la línea del return.
>
> char BuscarPorNombre (char inNombre[64]) {
En vez de copiar los 64 caracteres, deberías pasarlo como const char* 
inNombre. Apuntando a los datos.
>      int i;
>      for (i=0; i<10; i++)
>           {
>           if (inNombre == BaseTelfs[i].nombre)
>              {break;}
>           }
>      return BaseTelfs[i].telf;
> }
Fallará si no encuentra el teléfono. En ese caso intentará devolver 
BaseTelfs[10].telf, que no existe.
>
>
> Les dejo también aquí la estructura:
>
> struct telfs {
>        char telf[9],nombre[64];
>        }BaseTelfs[10];
>
>
> ¿Qué puede estar pasando?
El compilador te está avisando, con mucha razón, que guardas el teléfono 
como 9 caracteres. Pero cuando lo encuentras, lo devuelves como una 
letra. ¿Cómo va a devolverte el teléfono en una letra? Si guardas el 
teléfono como int sí podrías devolverlo directamente. Con caracteres, 
tendrías que pasar punteros.


> Me parece que no acabo de entender la sistemática de las cadenas en C++,
En realidad son las cadenas de C. Una cadena es un conjunto de letras. 
Por tanto trabajas con ellas con un puntero, que apunta al conjunto de 
letras.
> ¿Por qué no pueden compararse con el operador ==?
Porque comparas las direcciones de memoria del puntero, no las letras.
> ¿Qué debo hacer entonces para compararlas?
if (!strcmp(inNombre, BaseTelfs[i].nombre))



Si trabajas en C++, te será mucho más comodo trabajar con la clase 
string de la stl en vez de con cadenas de tipo C.
Con ella el ejemplo sería así:


#include <string>
using namespace std;

struct telfs {
       string telf[9];
       string nombre[64];
}BaseTelfs[10];


string BuscarPorNombre (const string& inNombre) {
     int i;
     for (i=0; i<10; i++)
          {
          if (inNombre == BaseTelfs[i].nombre)
             {return BaseTelfs[i].telf; }
          }
     return "No hay teléfono";
}



Si arreglásemos el código con cadenas tipo C sería:

const char* BuscarPorNombre (const char* inNombre) {
     int i;
        for (i=0; i<10; i++)
          {
          if (!strcmp(inNombre, BaseTelfs[i].nombre))  {
                return BaseTelfs[i].telf;  //Esto es peligroso, pues 
estamos devolviendo punteros a cadenas. Al ser una estructura externa 
funciona. Pero en otros casos el programa fallaría.
           }

       return "No hay teléfono";
}





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