hasrha_sr
hasrha_sr

Reputation: 11

fread of binary file returning negative value

I am setting up 3 pointers to same file, each will work at a different offset. I need to read 1 byte at a time from each of them. But the fread of second pointer always showing a negative value.

int main(void) {
    unsigned int y; 
    unsigned int u; 
    unsigned int v; 
    FILE *yPtr;
    FILE *uPtr;
    FILE *vPtr;
    yPtr = fopen ( "test.bin", "rb"); 
    uPtr = fopen ( "test.bin", "rb"); 
    vPtr = fopen ( "test.bin", "rb"); 
    fread(&y,1,1,yPtr);
    fread(&u,1,1,uPtr); 
    fread(&v,1,1,vPtr);

    printf("%x ", y);
    printf("%x ", u);
    printf("%x ", v);

}

I expect: "9f 9f 9f" But output is : "9f ffffcc9f 9f"

Upvotes: 0

Views: 1287

Answers (4)

micheal007
micheal007

Reputation: 147

You should change unsigned int into a unsigned char or uint8_t,byte etc...

Upvotes: 0

Achal
Achal

Reputation: 11921

Here:

unsigned int y; /* unintialized, default contains garbage data due to automatic storage */

In a 32-bit system, four bytes of memory are reserved for y. It looks like

 0x100   0x101    0x102   0x103      let's assume base address of y is 0x100
-----------------------------------
|   G   |   G     |  G     |   G  |  G- garbage
-----------------------------------
y
LSb-->                 

And here

fread(&y,1,1,yPtr);

fread() is reading only 1 byte from yPtr and storing into y. Now it looks like

0x100               0x101    0x102   0x103  
--------------------------------------------
|   valid value   |   G     |  G     |   G  |  G- garbage
--------------------------------------------
y

So except first bytes, remaining bytes contains still some intermediate values.

Correct is

fread(&y, 4, 1, yPtr); /* read 4 bytes */

Or initialize the variable first. For example,

unsigned int y = 0; /* now if only first byte overwritten, remaining byte contents will be zero */ 

Or if your application's intention is to read only 1 byte then use unsigned char type instead of unsigned long type. For e.g

unsigned char y = 0;

Same applicable for other variable u and v & respective fread() statements. Also do check the return values of library function fopen() and fread().

Upvotes: 3

cocool97
cocool97

Reputation: 1251

Try the following code.
It seems you're writing a 1-byte value in a value larger than that (depending on the CPU) which is not initialized.
An unsigned char is 1 byte, so you shouldn't have any problems:

int main(void) {
    unsigned char y = 0, u = 0, v = 0; 

    FILE *yPtr, *uPtr, *vPtr;
    yPtr = fopen ("test.bin","rb"); 
    uPtr = fopen ("test.bin","rb"); 
    vPtr = fopen ("test.bin","rb"); 

    fread(&y,1,1,yPtr);
    fread(&u,1,1,uPtr); 
    fread(&v,1,1,vPtr);

    printf("%x %x %x", y, u, v);
}

Upvotes: 2

Petr Skocik
Petr Skocik

Reputation: 60107

unsigneds are usually 4-8 bytes. You're reading just 1 byte into them, leaving the rest indeterminate.

If you want to read just one byte, you should read it into an unsigned char.

If you want to keep using unsigned ints, you could pre-zero them, and then you'd get the result you want provided you're on a two's complement machine.

In real code, you should also be checking your return values (at least for fopen and fread).

Upvotes: 4

Related Questions