feof() problem, it doesn't do it's job...


Results 1 to 7 of 7

Thread: feof() problem, it doesn't do it's job...

  1. #1
    Join Date
    Jun 2000
    Location
    Maringá
    Posts
    77

    feof() problem, it doesn't do it's job...

    Hi guys, i'm having a little problem using the feof() function in Borland C++ for 3.1 for DOS, here's the code i'm trying to make work, it just store to long unsigned int number inside a file, well here it is:
    Code:
    FILE *arq_index;
    
    // This function writes to the file
    void insert(unsigned long int RA, unsigned long int OFFSET){
         arq_index=fopen("index.idx","ab+");
         fwrite(&RA,sizeof(RA),1,arq_index);
         fwrite(&OFFSET,sizeof(RA),1,arq_index);
         fclose(arq_index);
    }
    
    //This functions tries to read the file
    void read(){
         unsigned long int RA=0, OFFSET=0;
         arq_index=fopen("index.idx","rb");
         if (arq_index){
              rewind(arq_index);
              clrscr();
              while (!feof(arq_index)){
                   OFFSET=0;
                   RA=0;
                   fread(&RA,sizeof(RA),1,arq_index);
                   fread(&OFFSET,sizeof(OFFSET),1,arq_index);
                   printf("%s\n%s%ld\n%s%ld\n","------------------","RA : ",RA,OFFSET : ",OFFSET);
              }
              fclose(arq_index);
         }
    }
    Well, the problem is the following, let's say that I do the this :
    Code:
    void main(){
         for(int x=0; x < 2; x++)
              for(int y=0; y < 2; y++)
                   insert(x,y);
    }
    this will put the following numbers into the file : [0,0];[0,1];[1,0];[1,1], until here, nothing special, more simples than this, impossible, but the problem comes when i'm reading the file, like this:

    Code:
    void main(){
    /*
         for(int x=0; x < 2; x++)
              for(int y=0; y < 2; y++)
                   insert(x,y);
    }
    */
         read();
    }
    It prints out the following
    Code:
    ------------------
    RA : 0
    OFFSET : 0
    ------------------
    RA : 0
    OFFSET : 1
    ------------------
    RA : 1
    OFFSET : 0
    ------------------
    RA : 1
    OFFSET : 1
    ------------------
    RA : 0
    OFFSET : 0
    this last entry that's making me insane, why does it always print one more entry, no matter how many entries i put in it, it always prints out one more entry, so, i went debbuging the problem, i found that the problem is that the feof() function in :
    while (!feof(arq_index)){ isn't finding the end of the file in its first attemp, like this, it reads the last register off the file, but, the feof() still lets the branch true, so it enters again, than the fread functions returns erros ( the zeros on the last entry) and then it comes back to the branch, only now it will be false... but why is that ?? i did an hexdump on the file, nothing wrong with its EOF char, any ideas ?

    [ 19 April 2002: Message edited by: MaGneTTo ]
    WhErEvEr YoU aRe, YoU'lL bE tHeRe ...

  2. #2
    Join Date
    Jun 2000
    Location
    Houston, TX, USA
    Posts
    1,290
    I've run into this before, and I remember having to do something different, but can't recall what. It may have been reading once, then entering a do...while loop - I know, it's a pain, but I think you have to do that. Not sure why...
    "I'm not closed-minded, you're just wrong" - Bucky Katt

  3. #3
    Join Date
    Jan 2001
    Location
    Yonkers, NY USA
    Posts
    525
    I tried rewriting your read function using full error checking and such and this works for me:
    Code:
    void read(void)
    {
      unsigned long int RA, OFFSET;
      FILE *fp;
    
      RA = OFFSET = 0;
    
      printf("\033[2J"); /* ANSI Clearscreen */
    
      if((fp = fopen("index.idx", "rb")) == NULL) {
        perror("FILE");
        exit(1);
      }
    
      if(fseek(fp, 0L, SEEK_SET)) {
        perror("RANDOM ACCESS");
        exit(2);
      }
    
      while(1) {
        fread(&RA,sizeof(RA),1,fp);
        fread(&OFFSET, sizeof(OFFSET), 1, fp);
    
        if(feof(fp)) break;
                  printf("%s\n%s%ld\n%s%ld\n","------------------","RA : ",RA, "OFFSET : ",OFFSET);
      }
    
      fclose(fp);
    
    }
    BTW why were you making the FILE a global variable?

    [ 20 April 2002: Message edited by: debiandude ]
    Get my public gpg key

  4. #4
    Join Date
    Jan 2001
    Location
    Yonkers, NY USA
    Posts
    525
    Okay this is why feof dosn't work right for you. Basically an end of file condition does not exist even if all the characters in the file have been read. You need to read past the last character to get eof. Thats why you were getting that error.


    I think of it like this. You open a file 3 bytes long and your position at the file is nothing. You preform fread and you read a bite you position is at the first byte. You preform fread again and your position is at byte two. You preform fread and get the last byte, you position is at byte 3. You preform feof and it passes becuase your position is still at byte 3, its not checking the next byte! So it goes back into the loop. fread checks byte 4 (eof baby) and fread says hay thats wrong and returns -1 or 0 or something. Now feof, which won't advance the pos, says yup the byte were at is eof and the loop exits. That make it better.

    [ 19 April 2002: Message edited by: debiandude ]
    Get my public gpg key

  5. #5
    Join Date
    Jun 2000
    Location
    Maringá
    Posts
    77
    Nice explanation debiandude, now i see why this d*wm thing wasn't working, and the FILE* is a global variable in this example i gave you guys, it's a much bigger program, i spent almost a week to get to this fscking error, about the code you "corrected" i may say that i'm a bit lost, even knowing what it's doing, thank you all. I solved it by doing the eof check by the fread() function, it works great, much better that feof()...
    WhErEvEr YoU aRe, YoU'lL bE tHeRe ...

  6. #6
    Join Date
    Jan 2001
    Location
    Yonkers, NY USA
    Posts
    525
    Hrm what didn't you understand or follow about my code?

    Also as a side not I don't think you should be checking for EOF from fread. fread does not return the character it has read!!! It returns the number the number of items successfully read. So in your case you would do:
    Code:
    if(fread(&RA,sizeof(RA),1,fp) != 1) break;
    You could in some instance run into truoble by checking its retrun against EOF.

    Here is why. First off, fread returns on error or end-of-file a 0 or a number < number of elements (1 in your case). What this means is that you do not know wether an error has occoured or you just reached the end-of-file. Which means a subsequent call to feof or ferror. Thats why in the code above I used a feof to check for eof.

    [ 21 April 2002: Message edited by: debiandude ]
    Get my public gpg key

  7. #7
    Join Date
    Apr 2013
    Location
    Barakaldo, Vizkaya.
    Posts
    1
    Hi every body I know the Thread is very old but this problems occur and will occur a lot of more times.
    The trick is this :
    OFFSET=0;
    RA=0;
    fread(&RA,sizeof(RA),1,arq_index);
    fread(&OFFSET,sizeof(OFFSET),1,arq_index);
    while (!feof(arq_index)){
    printf("%s\n%s%ld\n%s%ld\n","------------------","RA : ",RA,OFFSET : ",OFFSET);
    fread(&RA,sizeof(RA),1,arq_index);
    fread(&OFFSET,sizeof(OFFSET),1,arq_index);
    }
    First of all never declare the variables in a loop, then You have to read the files before the while loop, then inside the loop do what ever You want, and in the end You have to read again the files. This is the correct way it works.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •