Why the last iteration repeats?

186 views Asked by At

My question refers to the while(!feof(arch)) that repeats the last registry two times. Thanks if you take some of your time to answer. I'm in first year learning basics.

The information is on an archive, so the first input shouldn't be 's' because it isn't the first time to input. Then the program list the infomation but the last registry repeats two times.

#include <stdio.h>

typedef struct{
    int legajo;
    char nombre[30];
    int ingreso;
    int pparcial;
    int sparcial;
} reg_alumno;

reg_alumno funcionleer(void);

typedef FILE * archivo; //Se define el tipo de dato "archivo".

archivo arch; //Se declara una variable de archivo.

int main(void){
    reg_alumno alumno,alu;
    int ca,i,j=0;
    char respuesta;
    printf("Desea ingresar datos por primera vez?");
    scanf("%c",&respuesta);
    printf("Ingrese cantidad alumnos");
    scanf("%d",&ca); //Pide cantidad alumnos
    if(respuesta=='s'){
        arch = fopen("alumnos.dat","w"); //Crear archivo para escribir, crea si no existe)
        for(i=0;i<ca;i++){
            alumno = funcionleer(); //Lee alumno
            fseek(arch,sizeof(reg_alumno)*i,SEEK_SET); //Busca la última posición del archivo
            fwrite(&alumno,sizeof(reg_alumno),1,arch); //Escribe en la última posición 
        }
    }
    else{
        arch = fopen("alumnos.dat","r+");
        while(!feof(arch)){
            fseek(arch,sizeof(reg_alumno)*j,SEEK_SET); //Pasa de registro en registro(alumno en     alumno).
            fread(&alu,sizeof(reg_alumno),1,arch); //Trae a la memoria principal un alumno
            printf("Legajo N %d: %s\n",alu.legajo,alu.nombre);
            j++;
        }
    }
fclose(arch); //Cierra el archivo
}

reg_alumno funcionleer(void){ //Función leer
    reg_alumno alumno;
    printf("Ingrese el numero de legajo:\n");
    scanf("%d",&alumno.legajo);
    printf("Ingrese el nombre:\n");
    scanf("%s",alumno.nombre);
    return(alumno);
}
1

There are 1 answers

0
chux - Reinstate Monica On BEST ANSWER

Good to check result of IO operations @WhozCraig.

The code's problem is that its prints even if fread() fails.

// No check of return value.
fread(&alu,sizeof(reg_alumno),1,arch);
printf("Legajo N %d: %s\n",alu.legajo,alu.nombre);

Code uses feof() incorrectly. Many SO posts on that.

Since OP implies code is required to use feof() by teacher: following are 2 good ways to use feof()

 for (;;) {
   if (fseek(arch,sizeof(reg_alumno)*j,SEEK_SET)) break;
   if (fread(&alu,sizeof(reg_alumno),1,arch) == 0) break;
   printf("Legajo N %d: %s\n",alu.legajo,alu.nombre);
   j++;
 }
 // If loop quit because of EOF
 if (feof(arch)) printf("Success");
 else if (!ferror(arch)) printf("IO Error");

Or

 for (;;) {
   if (fseek(arch,sizeof(reg_alumno)*j,SEEK_SET)) break;
   fread(&alu,sizeof(reg_alumno),1,arch);
   if (!feof(arch)) break;
   if (!ferror(arch)) break;
   printf("Legajo N %d: %s\n",alu.legajo,alu.nombre);
   j++;
 }