1

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);
}
Antú Villegas
  • 51
  • 1
  • 10
  • 2
    http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong – M.M Nov 24 '14 at 23:12
  • 2
    instead of `while (!feof)`, abort loop if `fseek` or `fread` fails. – M.M Nov 24 '14 at 23:12
  • You never increment "j". – shooper Nov 24 '14 at 23:13
  • Maybe I don't understand. Can you show me the code with the for loop, and not the feof? In the above case (where you use feof and while) you will never reach the end of the file because you are always setting to the beginning of the file; maybe some problem like that with the for loop, but I am not sure where you are coming from as with the for loop you don't necessarily use feof. – shooper Nov 24 '14 at 23:22
  • If you bothered to check even *one* of your IO operations for failure, it may help deduce where the wheels are falling off. The link Matt posted *should be read in-detail*, including correct methods for doing what you're trying. – WhozCraig Nov 24 '14 at 23:23
  • 1
    Don't use `feof` to determine when to terminate your input loop. Instead check the value returned by *all* input functions you call, and terminate the loop if one of them fails. Check the documentation for each one to see how it reports failure. For one thing, if there's an input *error*, `ferror()` will become true but `feof()` won't, giving you an infinite loop. Use `feof()` and/or `ferror()` *after* the loop terminates to tell you why it terminated. – Keith Thompson Nov 24 '14 at 23:29
  • @shooper http://puu.sh/d4gGO/64e27d28a5.c Here it is the code using 'for' – Antú Villegas Nov 24 '14 at 23:34
  • The problem is that the teacher told us to use !feof, but seen it doesn't help at all – Antú Villegas Nov 24 '14 at 23:39
  • That code you have shared also never reaches end of file, but I cannot see that it would evidence the same problem as you are saying you have above. I would tend to think you should probably check your error codes (as people above have mentioned). Chances are something is failing for you, and it will become much clearer when you see what the error is. – shooper Nov 24 '14 at 23:41
  • @AntúVillegas you should print, then show, the top two answers in the linked question provided by Matt to your instructor. Judging by the number of times in a given week this issue arrises, a little reverse-education is likely in order. I doubt seriously the instructor *really* understands what is wrong with that construct. – WhozCraig Nov 25 '14 at 06:18

1 Answers1

1

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++;
 }
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256