Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: milx86 en 11 Octubre 2014, 02:15 am



Título: Funcion que no puede retornar un struct [C]
Publicado por: milx86 en 11 Octubre 2014, 02:15 am
Hola a todos, espero se cuentren bien.
Necesito de su ayuda, tengo una función que recibe una clave DNI, y va a buscar en un archivo con registros de longitud fija.
Si logra encontrar un registro que tenga ese DNI deve devolver una copia de ese registro, entonces ¿que debería de poner en lugar de esos NULL para el caso de que no se encuentre el registro? ¿Que tengo que devolver?

Código
  1. Record searchRecord(char* nameFile, char* DNI)
  2. {
  3.    FILE* fd;
  4.    if( (fd=fopen(nameFile,"rt")) == NULL )
  5.    {
  6.        printf("\nCould not open the file.");
  7.        return NULL;
  8.    }
  9.    else
  10.    {
  11.        struct Header header;
  12.        struct Record tmp;
  13.  
  14.        fread(&header, 1, headerLength, fd);
  15.  
  16.        while(fread(&tmp, 1, recordLength, fd) != NULL)
  17.        {
  18.            if(strncmp(DNI,tmp.DNI,strlen(tmp.DNI)) == 0)
  19.            {
  20.                struct Record data = tmp;
  21.                return data;
  22.            }
  23.        }
  24.        printf("\nData not found");
  25.        fclose(fd);
  26.    }
  27.  
  28.    return NULL;
  29. }

Gracias por su tiempo.



El compilador tambien me da una alerta en esta linea  :P.
Código:
while(fread(&tmp,recordLength, 1, fd) != NULL)
warning: comparison between pointer and integer [enabled by default]|
Edito:
Segun lo poco que entiendo, NULL se usa cuando trabajamos con punteros y fread devuelve un entero, pero no tengo idea que ponerle en lugar de NULL para evitar esos warnings.
Támbien estuve viendo que
fread el primer parámetro es un puntero. Creo eso no me cuesta nada crearlo para trabajar como se debe  :P
http://www.cplusplus.com/reference/cstdio/fread/
En fin, creo que me resulta hacer que devuelve un puntero de tipo Record.
No quería hacerlo, porque tenia la idea que solo necesito mostrar el registro y no editarlo XD pero que tonto, aunque mande un puntero y se llegase a modificar, el archivo sigue igual  :laugh:


Título: Re: Funcion que no puede retornar un struct [C]
Publicado por: rir3760 en 11 Octubre 2014, 03:33 am
Si logra encontrar un registro que tenga ese DNI deve devolver una copia de ese registro, entonces ¿que debería de poner en lugar de esos NULL para el caso de que no se encuentre el registro? ¿Que tengo que devolver?
Lo primero que debes hacer es publicar la declaración del alias (o macro) "Record" ya que la respuesta a tu problema depende de esa declaración (o definición, depende del caso). Lo mismo aplica a headerLength y recordLength.

fread devuelve un entero, pero no tengo idea que ponerle en lugar de NULL para evitar esos warnings.
El prototipo de fread es:
Código
  1. int fread(
  2.   void *addr,        /* Direccion donde se almacenaran los caracteres */
  3.   size_t size_elem,  /* Numero de bytes por elemento */
  4.   size_t num_elem,   /* Numero de elementos a leer   */
  5.   FILE *in           /* stream del cual se leeran los caracteres */
  6. );
La función trata de leer de "in" un numero de bytes igual a size_elem * num_elem y los almacena a partir de la dirección addr. Si no se utiliza el valor de retorno de la función el orden del segundo y tercer argumento no importa. La función después del intento de lectura retorna un entero igual al numero de bytes leídos entre el numero de bytes por elemento.

En base a lo anterior el bucle que mencionas se debe cambiar a (para leer elemento por elemento del archivo):
Código
  1. /* Mientras se lea con exito un registro del archivo */
  2. while (fread(&tmp, recordLength, 1, fd) == 1){
  3.   /* Comparar el campo del registro con el valor buscado */
  4.   if (strncmp(DNI,tmp.DNI,strlen(tmp.DNI)) == 0){
  5.      struct Record data = tmp;
  6.      return data;
  7.   }
  8. }

También hay que realizar otros cambios al programa, entre ellos:

* En caso de error puedes utilizar la función perror para que el mensaje de error se genere automáticamente.
* Si encuentras un registro con el valor buscado no cierras el archivo.
* La función strncmp solo compara los primeros N caracteres, si el valor del campo es "123" y el valor buscado "123456" la función retornara verdadero cuando las cadenas son distintas.

Un saludo


Título: Re: Funcion que no puede retornar un struct [C]
Publicado por: milx86 en 11 Octubre 2014, 03:39 am
Muy clara tu explicación rir3760 , muchas gracias.