0

I tried cyclically read file in buffer of 100 byte. When i read file first time - buffer was full. Returned value is 0. No error and no eof (functions "ferror" and "feof" shows no error). Then i tried read file second time and again returned value is 0, no error and no eof. But then i have empty buffer. I don't know what is the problem?

if(fopen_s(&file_in, argv[1], "rb") == 0){ 
    printf("File was opened.\n");

    while(!feof(file_in)){ 
        read_code = fread_s(file_data, 100, sizeof(unsigned char), 100, file_in); 
        if(ferror(file_in)) {
            printf("Error!\n");
        }
        if(feof(file_in)) {
            printf("Eof!\n");
        }
        printf("Read result: %d\n", read_code);
        /*Using the buffer*/
        memset(file_data, 0, 100);
    }
    fclose(file_in);
}
murzagurskiy
  • 1,273
  • 1
  • 20
  • 44
  • Don't do `while (!feof(...))`, it will not work the way you expect it to. Instead do e.g `while (fread_s(...) == ...)`. The reason is that the `EOF` flag is not set until after you try to read from the end of the file. – Some programmer dude Jun 24 '14 at 18:10
  • 7
    It would be helpful if you actually passed an integer **argument** to `printf("Read result: %d\n");` – WhozCraig Jun 24 '14 at 18:11
  • 1
    Also, the `fopen_s` and `fread_s` functions are extensions in the Microsoft C library, they are not standard on other platforms or libraries. – Some programmer dude Jun 24 '14 at 18:12
  • 3
    Note that a version of the `fopen_s()` and other `*_s()` functions are standardized in C11 in Annexe K as an optional but normative part of the standard. That said, the only implementation I know of is the Microsoft implementation, and there are points where what Microsoft implements does not match what the standard specifies. See [Do you use the TR-24731 'safe' functions?](http://stackoverflow.com/questions/372980/do-you-use-the-tr-24731-safe-functions) for more information. – Jonathan Leffler Jun 24 '14 at 18:16
  • `printf("Read result: %d\n");` --> `printf("Read result: %d\n", read_code);` would help. – chux - Reinstate Monica Jun 24 '14 at 18:20
  • Isn't `memset(file_data, 0, 100);` erasing the next 100 bytes that you are trying to read on the next loop? – Canella Jun 24 '14 at 18:21
  • Yes! Thanks, i just forgot this! But problem still here! Now it's result 100 first time and result 0 second time. – murzagurskiy Jun 24 '14 at 18:22
  • @Canella, no. It's erasing 100 bytes that i used already. – murzagurskiy Jun 24 '14 at 18:24
  • @JoachimPileborg I change code in your way but problem still here – murzagurskiy Jun 24 '14 at 18:28
  • Ok, so are you not forgeting to increase the cursor of the `file_data` to the next position? I mean, after you read the 100 bytes, you should skip to the next 100 bytes. something like `file_data += 100` at the end of the loop; I am not very familiar with `fread`, but from what I remember, it doesn't move the cursor automatically to the next position. – Canella Jun 24 '14 at 18:32
  • @gek0n what does the declaration of `file_data` look like? – AndersK Jun 24 '14 at 18:45
  • @Claptrap unsigned char file_data[100] = {0}; – murzagurskiy Jun 24 '14 at 18:58
  • @gek0n the file you are trying to read, how large is it? Is the file shared by some other process? – AndersK Jun 24 '14 at 19:04
  • "But problem still here! Now it's result 100 first time and result 0 second time" How is this bad? What did you expect? – chux - Reinstate Monica Jun 24 '14 at 20:29
  • @chux i expect result 100 first and second time. Size of file 5 Mb, so it would be reading every 100 byte with result 100. But instead it's result 100 only first time. I think it's problem after first reading – murzagurskiy Jun 25 '14 at 04:36
  • @gek0n in the section "/* using the buffer */" is probably where the problem is. – AndersK Jun 25 '14 at 06:23
  • @Claptrap why? It's problem with READING not with buffer – murzagurskiy Jun 25 '14 at 15:01
  • @gek0n In C when you somewhere else in the program overwrite memory or stack you may get crashes in other parts of the program. – AndersK Jul 03 '14 at 16:25

1 Answers1

1

For the reasons given in comments regarding fopen_s, et. al., Here is an alternative implementation of reading a binary file using getc(), along with fopen(), fclose(), etc. (I am not using a Microsoft implementation, but am using ANSI C99)

It has a commented section I used to create a test binary file. Other than that it sizes the file you are reading so you can allocate the right amount of memory, then reads the binary data into a buffer.

For navigating your file, take a look at fseek() with its stdio.h defined arguments:

#define SEEK_SET     0
#define SEEK_CUR     1
#define SEEK_END     2

In this example, everything is closed or freed before exiting:

#include <windows.h>
#include <ansi_c.h>

long int getFileSizeFromPath(char * path)
{
    FILE * file;
    long int fileSizeBytes = 0;
    file = fopen(path,"r");
    if(file){
        fseek(file, 0, SEEK_END);
        fileSizeBytes = ftell(file);
        fseek(file, 0, SEEK_SET);
        fclose(file);
    }
    return fileSizeBytes;
}

int main(int argc, char *argv[])
{
    FILE *fp=0;
    char *binBuf;
    long int size=0;
    int i=0;
    int byte=0;

//create 100 byte test file (c:\\dev\\tessst.bin)   
//  fp = fopen(argv[1], "wb");
//
//  srand(clock()); 
//  for(i=0;i<100;i++)
//  {
//      byte = rand();
//      putc(byte, fp); 
//  }
//  putc(EOF, fp);
//  
//  fclose(fp);

    size = getFileSizeFromPath(argv[1]);
    binBuf = calloc(size + 1, sizeof(char));

    fp = fopen(argv[1], "rb");
    byte = getc(fp);
    while(byte != EOF)
    {
        binBuf[i++] = (char)byte;
        byte = getc(fp);
    }
    fclose(fp);
    free(binBuf);

    return 0;
}
ryyker
  • 22,849
  • 3
  • 43
  • 87
  • Minor curiosity. Why not use `long fileSizeBytes, long getFileSizeFromPath()` instead of `int fileSizeBytes` as `ftell()` returns `long`? – chux - Reinstate Monica Jun 24 '14 at 20:34
  • 2
    BTW: `char byte` --> `int byte` else the `while(byte != EOF)` loses the ability to distinguish EOF from, say, 255. – chux - Reinstate Monica Jun 24 '14 at 20:41
  • 1
    @chux - Good points both. Will edit. (but in context. I created this whole code segment with the OPs question in mind about a 100 byte file size :) I see your point on the use of `int` rather than `char` for `byte`. Thanks. – ryyker Jun 24 '14 at 21:19