Reputation: 11
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
Reputation: 147
You should change unsigned int into a unsigned char or uint8_t,byte etc...
Upvotes: 0
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
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
Reputation: 60107
unsigned
s 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 int
s, 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