Robert777
Robert777

Reputation: 801

Unexpected output when using fseek

Assuming we have a text file named hi.txt that contains the following string:

AbCdE12345

Let say we run this code:

int main() {
  FILE *fp;
  fp = fopen("hi.txt","r");
  if(NULL == fp) { return 1; }
  fseek(fp,-1, SEEK_END);
  while (ftell(fp) > 0) {
     printf("%c",fgetc(fp));
     fseek(fp,-4, SEEK_CUR);
  }
  fclose(fp);
  return 0;
}

When I ran this code it printed: 3EbCd

When I tried to guess what it would print I thought that it should be 52d. Can anyone explain what has happened here ?

Upvotes: 5

Views: 266

Answers (2)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726489

It looks like there is a non-printable end-of-line character at the end of your file. That's what gets printed first. Then the position is moved in turn to 3, E, and b. At this point, re-positioning by -3 fails, because the location would become -2. File cursor stays where it was, i.e. at C which gets printed next. The following attempt at repositioning fails too, so d gets printed. The next repositioning succeeds, terminating the loop.

To detect situations when fseek is ignored, check its return value, like this:

while (ftell(fp) > 0) {
    printf("%c",fgetc(fp));
    // Successful calls of fseek return zero
    if (fseek(fp,-4, SEEK_CUR)) {
        // Exit the loop if you can't jump back by 4 positions
        break;
    }
}

Upvotes: 15

Kninnug
Kninnug

Reputation: 8053

For files opened in text mode the offset passed to fseek is only meaningful for values returned by ftell. So the offset may not necessarily be in bytes. Try opening the file in binary mode:

fp = fopen("hi.txt", "rb");

and see if the results are different.

Upvotes: 4

Related Questions