I've a rather curious question, not very practical at all really. The error (reading a binary file in `r` mode) is in plain sight but I'm confused by something else.

Here's the code-

```c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdint.h>

#define BUFFER_LEN 512

typedef uint8_t BYTE;

int main()
{
    FILE* memcard = fopen("card.raw", "r");
    BYTE buffer[BUFFER_LEN];
    int count = 0;
    while (fread(buffer, sizeof(*buffer), BUFFER_LEN, memcard) != 0)
    {
        printf("count: %d\n", count++);
    }
    fclose(memcard);
    return 0;
}

```

Now, `card.raw` is a binary file, so this reading *will* go wrong due to being read in `r` mode instead of `rb`. But what I'm curious about is that, that loop executes exactly 3 times, in the final execution, it doesn't even read 512 bytes.

Now if I change that loop to

```
while (fread(buffer, sizeof(*buffer), BUFFER_LEN, memcard) != 0)
{
    printf("ftell: %ld\n", ftell(memcard));
}

```

It no longer stops at 3 executions. In fact, it keeps going until (presumabely) the end of file. The `fread` count is still messed up. Many of the reads do not return 512 as elements read. But that is most probably due to the file being opened in `r` mode and all the encoding errors it's being accompanied with .

`ftell` shouldn't affect the file itself, then why does including `ftell` in the loop make it execute more times?

I decided to change the loop a bit more to extract more info-

```c
while ((count = fread(buffer, sizeof(*buffer), BUFFER_LEN, memcard)) != 0)
{
    printf("fread bytes read: %d\n", count);
    printf("ftell: %ld\n", ftell(memcard));
}

```

This loops just as many times as it would, provided `ftell` is included in the loop and the first few results look like-

[![ftell results](https://i.stack.imgur.com/JeQwE.png)](https://i.stack.imgur.com/JeQwE.png)

Now if I just remove that `ftell` line completely, it gives me-

[![without ftell results](https://i.stack.imgur.com/znfQB.png)](https://i.stack.imgur.com/znfQB.png)

Only 3 executions, yet nothing changed.

What's the explanation behind this behaviour?

Note: I know the counts returned by both `fread` and `ftell` are probably wrong due to the read mode, that's not my concern though. I'm only curious - why the difference, between including `ftell` and not including it.

Also, in case it helps, The `card.raw` file is actually just the cs50 pset4 "memory card". You can get it by `wget https://cdn.cs50.net/2019/fall/psets/4/recover/recover.zip` and storing the output file in a `.zip`

Edit: I should mention this was on windows and using clang tools for VS2019. The command line options (checked from VS2019 project properties) looked like-

```
/permissive- /GS /W3 "Debug\" "Debug\" /Zi /Od "Debug\vc142.pdb" /fp:precise /D "_CRT_SECURE_NO_WARNINGS" /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /WX- /Gd /MDd /Fa"Debug\" /EHsc /nologo /Fo"Debug\" /Fp"Debug\Test.pch" /diagnostics:column 

```

Edit: Also, I did check for `ferror` inside the loop, with and without `ftell`, got no errors from it at all. In fact, `feof` returns 1 after the loop, in both cases.

Edit: I also tried adding a `memcard == NULL` check right after the `fopen`, same behaviour.

Edit: To address the answer by @orlp. I did, infact, check for errors. I should definitely have posted it though.

```c
while ((count = fread(buffer, sizeof(*buffer), BUFFER_LEN, memcard)) != 0)
{
    if ((err = ferror(memcard)))
    {           
        fprintf(stderr, "Error code: %d", err);
        perror("Error: ");
        return 1;
    }
    printf("fread bytes read: %d\n", count);
    printf("ftell: %ld\n", ftell(memcard));
}
if ((err = ferror(memcard)))
{
    fprintf(stderr, "Error code: %d", err);
    perror("Error: ");
    return 1;

}

```

Neither of the 2 `if` statements are ever triggered.

Edit: I thought we got the answer already, it was `ftell` resetting the EOF. But I changed the loop to-

```c
while ((count = fread(buffer, sizeof(*buffer), BUFFER_LEN, memcard)) != 0)
{
    if ((err = ferror(memcard)))
    {
        fclose(memcard);
        fprintf(stderr, "Error code: %d", err);
        perror("Error: ");
        return 1;
    }
    if (feof(memcard))
    {
        printf("reached before\n");
    }
    printf("fread bytes read: %d\n", count);
    ftell(memcard);
    if (feof(memcard))
    {
        printf("reached after\n");
    }
}

```

this triggers both the first `if(feof)` and the second `if(feof)`

As expected though, if I change the `ftell` to `fseek(memcard, 0, SEEK_CUR)`, the `EOF` *is* reset and the `reached after` is never printed.