elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: AIO elhacker.NET 2021 Compilación herramientas análisis y desinfección malware


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Problema en C con la funcion fread y fwrite
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Problema en C con la funcion fread y fwrite  (Leído 6,348 veces)
M01535

Desconectado Desconectado

Mensajes: 4


Ver Perfil
Problema en C con la funcion fread y fwrite
« en: 26 Marzo 2015, 15:57 pm »

Buenas, estoy haciendo un ejercicio de programacion en C en el cual tengo que lograr lo siguiente: Crear un "struct" que almacene los siguientes datos de una persona: nombre, edad, ciudad de residencia. Pedir al usuario esos datos de una persona y guardarlos en un fichero llamado "gente1.dat", usando "fwrite". Cerrar el fichero, volverlo a abrir para lectura y mostrar los datos que se habían guardado, que se deben leer con "fread".

Aun me cuesta entender como funciona exactamente la orden fread y fwrite, por ejemplo, escribiendo: fread(&ficha, sizeof(ficha), 1, fichero); &ficha se refiere al lugar donde se guardan los datos, sizeof(ficha) el tamaño de los datos, el 1 a la cantidad de datos a leer, pero ¿hasta donde se lee?, ¿hasta que encuentre un \0 o \n?, no entiendo muy bien ese 1.

Bueno, aqui os dejo mi intento del ejercicio anterior, el cual casi al finalizar me tira "programa.exe has stopped working" y no se donde está el error.
Edit: Aclarar que el programa me da dos warning: "assignment make pointer from integer without a cast"
Código:
#include <stdio.h>
#include <string.h>

int main(){

struct{
char Name[100],City[100];
int Age;
}Persona;
FILE *Gente1;
int X;

if(Gente1=fopen("gente1.dat","ab")==NULL){
    printf("No se puede escribir en el fichero...\n");
}
else{
    printf("Que nombre deseas introducir?: ");
    fflush(stdin);
    gets(Persona.Name);
    printf("\nCiudad?: ");
    fflush(stdin);
    gets(Persona.City);
    printf("\nEdad?: ");
    fflush(stdin);
    scanf("%d",&Persona.Age);
    fwrite(&Persona,sizeof(Persona),1,Gente1);
    fclose(Gente1);
}

if(Gente1=fopen("gente1.dat","rb")==NULL){
    printf("\nNo se puede leer el fichero...\n");
}
else{
    while(!feof(Gente1)){
        fread(&Persona,sizeof(Persona),1,Gente1);
        puts(Persona.Name);
        puts(Persona.City);
        printf("%s\n",Persona.Age);
    }
    fclose(Gente1);
}

fflush(stdin);
getchar();
return 0;
}

Muchas gracias de antemano!


« Última modificación: 26 Marzo 2015, 16:05 pm por M01535 » En línea

ivancea96


Desconectado Desconectado

Mensajes: 3.412


ASMático


Ver Perfil WWW
Re: Problema en C con la funcion fread y fwrite
« Respuesta #1 en: 26 Marzo 2015, 16:19 pm »

Estas escribiendo y leyendo datos binarios. No se atiende ni a caracteres nulos ni a saltos de linea. Si tu le especificas leer X bytes, leerá X bytes, no más.

La cantidad de bytes que leerá fread en total, será el tamaño del tipo o estructura que le pasas (segundo parámetro), multiplicado por el número de elementos del arreglo (tercer parámetro.

fwrite es más de lo mismo.

Si quieres información detallada de las funciones, http://www.cplusplus.com/reference/cstdio/fread/.


En línea

M01535

Desconectado Desconectado

Mensajes: 4


Ver Perfil
Re: Problema en C con la funcion fread y fwrite
« Respuesta #2 en: 26 Marzo 2015, 17:08 pm »

Muchas gracias ivancea96 por tu respuesta, eso de la cantidad de bytes que leerá fread en total me ha quedado bastante claro ;-) Ahora bien, alguien tiene idea de por qué el programa me tira los warning: "assignment make pointer from integer without a cast" y al ejecutarlo, cuando va a finalizar el programa, deja de funcionar: "program.exe has stopped working"
En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: Problema en C con la funcion fread y fwrite
« Respuesta #3 en: 26 Marzo 2015, 17:32 pm »

alguien tiene idea de por qué el programa me tira los warning: "assignment make pointer from integer without a cast" y al ejecutarlo, cuando va a finalizar el programa, deja de funcionar: "program.exe has stopped working"
Los errores se generan en las llamadas a fopen:
Código
  1. if (Gente1 = fopen("gente1.dat","ab") == NULL){
  2.  
  3. /* ... */
  4.  
  5. if (Gente1 = fopen("gente1.dat","rb") == NULL){
El operador "==" tiene una prioridad mayor que "=" por lo que esas sentencias se procesan así:
Código
  1. if (Gente1 = (fopen("gente1.dat","ab") == NULL)){
  2.  
  3. /* ... */
  4.  
  5. if (Gente1 = (fopen("gente1.dat","rb") == NULL)){
Por ello la variable almacenara el valor entero cero si fopen tiene éxito y uno en caso contrario.

Para solucionarlo solo tienes que utilizar paréntesis para primero asignar y solo entonces comparar:
Código
  1. if ((Gente1 = fopen("gente1.dat","ab")) == NULL){
  2.  
  3. /* ... */
  4.  
  5. if ((Gente1 = fopen("gente1.dat","rb")) == NULL){

Por ultimo evita el uso de gets y fflush(stdin), las razones de ello en el tema |Lo que no hay que hacer en C/C++. Nivel basico|

Un saludo
En línea

C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language
M01535

Desconectado Desconectado

Mensajes: 4


Ver Perfil
Re: Problema en C con la funcion fread y fwrite
« Respuesta #4 en: 27 Marzo 2015, 01:12 am »

Muchas gracias por tu respuesta rir3760, me habeis ayudado bastante y he aprendido unas cuantas cosas nuevas, lo agradezo. He hecho unas "mejoras" al programa también teniendo en cuenta lo que me comentaste de fflush(stdin) y los gets, aqui tengo el nuevo codigo a ver que os parece
Código:
#include <stdio.h>
#include <string.h>

int main(){

struct{
char Name[100],City[100];
int Age;
}Persona;
FILE *Gente1;
int X;
char Buffer[200];

if((Gente1=fopen("gente1.dat","wb"))==NULL){
    printf("No se puede escribir en el fichero...\n");
}
else{
    printf("Que nombre deseas introducir?: ");
    fgets(Persona.Name,sizeof(Persona.Name),stdin);
    printf("\nCiudad?: ");
    fgets(Persona.City,sizeof(Persona.City),stdin);
    printf("\nEdad?: ");
    fgets(Buffer,sizeof(Buffer),stdin);
    sscanf(Buffer,"%d",&Persona.Age);
    fwrite(&Persona,sizeof(Persona),1,Gente1);
    fclose(Gente1);
}

if((Gente1=fopen("gente1.dat","rb"))==NULL){
    printf("\nNo se puede leer el fichero...\n");
}
else{
    while(!feof(Gente1)){
        fread(&Persona,sizeof(Persona),1,Gente1);
        if(strlen(Persona.Name)>0) Persona.Name[strlen(Persona.Name)-1]='\0';
        if(!feof(Gente1)) puts(Persona.Name);
        if(strlen(Persona.City)>0) Persona.City[strlen(Persona.City)-1]='\0';
        if(!feof(Gente1)) puts(Persona.City);
        if(!feof(Gente1)) printf("%d\n",Persona.Age);
    }
}
fclose(Gente1);

return 0;
}
En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: Problema en C con la funcion fread y fwrite
« Respuesta #5 en: 27 Marzo 2015, 04:01 am »

Para imprimir el registro almacenado en el archivo no necesitas de un bucle, en su lugar basta con una sentencia condicional donde se verifique el valor de retorno de la función (uno en caso de una lectura exitosa). De esta forma:
Código
  1. if (fread(&Persona, sizeof(Persona), 1, Gente1) == 1)
  2.   printf("%s%s%d\n", Persona.Name, Persona.City, Persona.Age);

Un saludo
En línea

C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language
M01535

Desconectado Desconectado

Mensajes: 4


Ver Perfil
Re: Problema en C con la funcion fread y fwrite
« Respuesta #6 en: 30 Marzo 2015, 12:31 pm »

Gracias a todos por vuestras respuestas, son de gran ayuda. Bueno, me surgió una nueva duda sobre fread y fwrite (la guerra que me está dando esta orden... :xD) asi que aprovecho este mismo tema para exponerla.
El programa a construir es el siguiente: Mejorar la agenda anterior (del apartado 6.4), para guardar y leer cada "ficha" (struct) de una vez, usando fwrite/fread y sizeof, como en el último ejemplo.
Y aqui teneis el código de la agenda de la que se habla:
Código:
#include <stdio.h>
#include <string.h>

int main(){

FILE* Agenda;
struct{
    char Name[100],Adress[100],Email[100],Movil[13];
    unsigned short int Day,Month,Year;
}Datos[100];
char Buffer[200],Buscar[200];
int X=0,Y,Menu,Algodon=0;

//LEER DATOS DEL FICHERO
Agenda=fopen("agenda.dat","rt");
while(!feof(Agenda)){
    fgets(Buffer,200,Agenda);
    if(feof(Agenda)) break;
    if(strlen(Buffer)>0) Buffer[strlen(Buffer)-1]='\0';
    strcpy(Datos[X].Name,Buffer);

    fgets(Buffer,200,Agenda);
    if(feof(Agenda)) break;
    if(strlen(Buffer)>0) Buffer[strlen(Buffer)-1]='\0';
    strcpy(Datos[X].Adress,Buffer);

    fgets(Buffer,200,Agenda);
    if(feof(Agenda)) break;
    if(strlen(Buffer)>0) Buffer[strlen(Buffer)-1]='\0';
    strcpy(Datos[X].Movil,Buffer);

    fgets(Buffer,200,Agenda);
    if(feof(Agenda)) break;
    if(strlen(Buffer)>0) Buffer[strlen(Buffer)-1]='\0';
    strcpy(Datos[X].Email,Buffer);

    fgets(Buffer,200,Agenda);
    if(feof(Agenda)) break;
    sscanf(Buffer,"%d",&Datos[X].Day);

    fgets(Buffer,200,Agenda);
    if(feof(Agenda)) break;
    sscanf(Buffer,"%d",&Datos[X].Month);

    fgets(Buffer,200,Agenda);
    if(feof(Agenda)) break;
    sscanf(Buffer,"%d",&Datos[X].Year);
    Algodon=1;
    X++;
}
fclose(Agenda);
if(Algodon==0){
    printf("No hay datos que leer...\n\n");
}
else if(Algodon==1){
    printf("Datos leidos...\n\n");
}

do{
    printf("1 - Introducir nuevo dato\n2 - Ver todos los nombres de los datos\n3 - Buscar\n0 - Salir\nQue desea hacer?: ");
    fgets(Buffer,sizeof(Buffer),stdin);
    sscanf(Buffer,"%d",&Menu);

    switch(Menu){
    //INGRESAR NUEVO DATO
    case 1:
    printf("\n\nNUEVO DATO:\nIngrese el nombre: ");
    fgets(Datos[X].Name,sizeof(Datos[X].Name),stdin);
    Datos[X].Name[strlen(Datos[X].Name)-1]='\0';

    printf("Ingrese la ciudad: ");
    fgets(Datos[X].Adress,sizeof(Datos[X].Adress),stdin);
    Datos[X].Adress[strlen(Datos[X].Adress)-1]='\0';

    printf("Ingrese el numero de movil: ");
    fgets(Datos[X].Movil,sizeof(Datos[X].Movil),stdin);
    Datos[X].Movil[strlen(Datos[X].Movil)-1]='\0';

    printf("Ingrese el email: ");
    fgets(Datos[X].Email,sizeof(Datos[X].Email),stdin);
    Datos[X].Email[strlen(Datos[X].Email)-1]='\0';

    printf("Ingrese el dia de nacimiento: ");
    fgets(Buffer,sizeof(Buffer),stdin);
    sscanf(Buffer,"%d",&Datos[X].Day);

    printf("Ingrese el mes de nacimiento: ");
    fgets(Buffer,sizeof(Buffer),stdin);
    sscanf(Buffer,"%d",&Datos[X].Month);

    printf("Ingrese su year de nacimiento: ");
    fgets(Buffer,sizeof(Buffer),stdin);
    sscanf(Buffer,"%d",&Datos[X].Year);
    X++;
    break;

    //MOSTRAR LOS NOMBRES DE TODOS LOS DATOS
    case 2:
        if(X==0){
            printf("\n\nNo hay datos que mostrar\n\n");
            break;
        }

    printf("\n\nEstos son los nombres de todos los datos:\n");
    for(Y=0;Y<X;Y++){
        printf("%d - %s\n",Y,Datos[Y].Name);
    }
    printf("\n");
        break;

    //BUSCAR DATO POR NOMBRE
    case 3:
        printf("\n\nIntroduzca el nombre del contacto que desea buscar: ");
        fgets(Buscar,sizeof(Buscar),stdin);
        Buscar[strlen(Buscar)-1]='\0';
        Algodon=0;

        for(Y=0;Y<X;Y++){
            if(strcmp(Buscar,Datos[Y].Name)==0){
                printf("\nSe ha encontrado este/os resultado/s:\n");
                printf("Name: %s\nAdress: %s\nPhone: %s\nEmail: %s\nBorn in: %d-%d-%d\n\n",Datos[Y].Name,Datos[Y].Adress,Datos[Y].Movil,Datos[Y].Email,Datos[Y].Day,Datos[Y].Month,Datos[Y].Year);
                Algodon=1;
            }
        }
        if(Algodon==0){
            printf("\nNo se han encontrado resultados...\n\n");
        }
    }
}while(Menu!=0);

//ESCRIBIR LOS DATOS EN EL FICHERO
Agenda=fopen("agenda.dat","wt");
for(Y=0;Y<X;Y++){
    fprintf(Agenda,"%s\n",Datos[Y].Name);
    fprintf(Agenda,"%s\n",Datos[Y].Adress);
    fprintf(Agenda,"%s\n",Datos[Y].Movil);
    fprintf(Agenda,"%s\n",Datos[Y].Email);
    fprintf(Agenda,"%d\n",Datos[Y].Day);
    fprintf(Agenda,"%d\n",Datos[Y].Month);
    fprintf(Agenda,"%d\n",Datos[Y].Year);
}
fclose(Agenda);

printf("\nSaliendo...");

return 0;
}

Bueno, para facilitar las cosas, las partes donde hay que sustituir e introducir un fread y fwrite son las siguientes:

fread
Código:
Agenda=fopen("agenda.dat","rt");
while(!feof(Agenda)){
    fgets(Buffer,200,Agenda);
    if(feof(Agenda)) break;
    if(strlen(Buffer)>0) Buffer[strlen(Buffer)-1]='\0';
    strcpy(Datos[X].Name,Buffer);

    fgets(Buffer,200,Agenda);
    if(feof(Agenda)) break;
    if(strlen(Buffer)>0) Buffer[strlen(Buffer)-1]='\0';
    strcpy(Datos[X].Adress,Buffer);

    fgets(Buffer,200,Agenda);
    if(feof(Agenda)) break;
    if(strlen(Buffer)>0) Buffer[strlen(Buffer)-1]='\0';
    strcpy(Datos[X].Movil,Buffer);

    fgets(Buffer,200,Agenda);
    if(feof(Agenda)) break;
    if(strlen(Buffer)>0) Buffer[strlen(Buffer)-1]='\0';
    strcpy(Datos[X].Email,Buffer);

    fgets(Buffer,200,Agenda);
    if(feof(Agenda)) break;
    sscanf(Buffer,"%d",&Datos[X].Day);

    fgets(Buffer,200,Agenda);
    if(feof(Agenda)) break;
    sscanf(Buffer,"%d",&Datos[X].Month);

    fgets(Buffer,200,Agenda);
    if(feof(Agenda)) break;
    sscanf(Buffer,"%d",&Datos[X].Year);
    Algodon=1;
    X++;
}
fclose(Agenda);

fwrite
Código:
Agenda=fopen("agenda.dat","wt");
for(Y=0;Y<X;Y++){
    fprintf(Agenda,"%s\n",Datos[Y].Name);
    fprintf(Agenda,"%s\n",Datos[Y].Adress);
    fprintf(Agenda,"%s\n",Datos[Y].Movil);
    fprintf(Agenda,"%s\n",Datos[Y].Email);
    fprintf(Agenda,"%d\n",Datos[Y].Day);
    fprintf(Agenda,"%d\n",Datos[Y].Month);
    fprintf(Agenda,"%d\n",Datos[Y].Year);
}
fclose(Agenda);

Muchas gracias por vuestra atención y un saludo. :D
En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: Problema en C con la funcion fread y fwrite
« Respuesta #7 en: 1 Abril 2015, 18:05 pm »

La recomendación anterior se mantiene: no utilices feof, en su lugar verifica el valor de retorno de la función en turno. También utiliza nombres descriptivos para las variables, "algodon" no lo es.

----

El bucle de lectura lo puedes sustituir con una sola llamada a fread:
Código
  1. int num_regs; /* Numero de registros */
  2.  
  3. /* ... */
  4.  
  5. // Leer datos del fichero
  6. Agenda = fopen("agenda.dat", "rb");
  7. num_regs = fread(Datos, sizeof Datos[0], 100, Agenda);
  8. fclose(Agenda);
Con ella se le indica a la función que lea un máximo de 100 registros del archivo y los almacene a partir de la dirección indicada por "Agenda". El numero actual de registros leídos se almacena en la variable "num_regs".

En la misma linea el bucle de escritura se sustituye por la llamada a función:
Código
  1. // Escribir los datos en el fichero
  2. Agenda = fopen("agenda.dat", "wb");
  3. fwrite(Datos, sizeof Datos[0], num_regs, Agenda);
  4. fclose(Agenda);

----

Ya por ultimo cuando se desea leer un valor de tipo unsigned short el especificador de formato con scanf y familia es "%hu".

Un saludo
En línea

C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
fread y fwrite con clases
Programación C/C++
newone 4 4,916 Último mensaje 23 Junio 2011, 23:40 pm
por newone
Usos fwrite, fread
Programación C/C++
diegoCmC 4 5,625 Último mensaje 13 Septiembre 2012, 21:42 pm
por diegoCmC
fread o alguna funcion para leer un bloc de notas
Programación C/C++
Erres 8 7,259 Último mensaje 5 Octubre 2012, 18:19 pm
por Erres
Función fread y saltos de línea
Programación C/C++
NathanD 8 6,019 Último mensaje 20 Marzo 2013, 20:25 pm
por NathanD
FILE y funcion fwrite()
Programación C/C++
m@o_614 3 2,794 Último mensaje 7 Septiembre 2013, 08:49 am
por Eternal Idol
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines