You should not be doing an fread() before checking whether the file opened.
You should not be doing an fread() before checking whether the file opened.
The same can be said about long too. It could be larger than 32 bits on some platforms. I know of one platform where a long is 36 bits wide!
It's better to read the data into a char buffer and extract the values from it. This solves all of the problems of data sizes and endianness.
Edit: Salem already mentioned this technique and provided sample code. You should follow that advice.
Last edited by christop; 08-30-2012 at 10:50 AM.
thanks a lot - and yeah im aware of the few little issues (with fread before open and %d instead of %u for unsigned int - though that was just a quick test to see if i was getting right values and not really necessary for the full program)...after further reading and stuff (thanks salem, and other sources) i now understand the issues with endianness. Could someone further explain the technique of reading in to a char buffer/array ? i attempted it and whilst the B and M values were stored correctly...im guessing (due to my results), that simply doing(for the fileheader/first structure) is incorrect.Code:unsigned char array[5]; /* ignore code (incorrect) - should be 14 size etc */ fread(array, 1, sizeof(array), image); data.fileMarker1 = array[0]; data.fileMarker2 = array[1]; data.bfSize = array[2]; data.unused1 = array[3]; data.unused2 = array[4]; data.imageDataOffset = array[5];
Salem's example of the code uses bit-shifting - is that necessary if so, why? Sorry if this seem obvious to some.
EDIT: upon further research, i realised the size of the array should obviously be sizeof(header) (the struct) which is 14...however, im still not 100% sure as to how to assign each member correctly (which is obviously the issue regarding my incorrect results and code). Has to do with the size of each data type in the struct > so for data.imageDataOffset, could i just assign it to the 10th member of the array, or is that the incorrect way of going about it, and bit shifting should be used instead
Last edited by igor; 09-04-2012 at 01:45 AM.
You can't really get away from the bit shifting, when you're reading an array of bytes and you want to assign that to data types which are wider than a byte (say an int).
Now if 0x78 0x56 0x34 0x12 were bytes in some unsigned char array, read from a file, then to reassemble the unsigned long, you would need to doCode:$ cat foo.c #include <stdio.h> int main () { unsigned long a = 0x12345678; size_t i; for ( i = 0 ; i < sizeof(a) ; i++ ) { unsigned char b = a & 0xff; a = a >> 8; printf("Byte %d is %02x\n", (int)i, b ); } return 0; } $ ./a.out Byte 0 is 78 Byte 1 is 56 Byte 2 is 34 Byte 3 is 12
0x78 + (0x56<<8)
and so on.
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
ahh okay, worked it out thanks a lot!! all seems to work fine (from the first 2 structures) on both little and big endien - EXCEPT one member, imagedataoffset is getting different results when printing as an unsigned int (%u, or %d for that matter)...on pc i get the value of 54 (which i believe is the correct value), on linux im getting 1107296310. However when printing as a char, %c, both print 6. Any idea as to why this is occurring ? As stated, all other members work fine for both platforms. (also just checked to ensure, all values of all 14 members of the array are the same on both platforms, with array[10] = 54, and array[11] to array[13] being 0 (the 4 bytes associated with the unsigned int) ).
Last edited by igor; 09-04-2012 at 03:27 AM.
54 in binary is 110110
1107296310 in binary is 1000010000000000000000000110110
As you can see the last byte is the same as 54. I guess you have some misalignmet issue
It would be easier to help you if you show the relevant code (structure definition and how you read the file into the array).
Bye, Andreas
That seems unlikely... maybe array[13] was 0 when you checked it but it's probably an uninitialized value, or at least it appears to be getting assigned 0x42 = 66 somehow! It's quite possible for uninitialized variables to suddenly look okay when you print them or in a debugger, and quite likely to be zero in visual studio in debug mode (I think it zeros all memory automatically).
Since it's the last element of the array, perhaps you're reading one less byte from the file than you should be? Try setting imagedataoffset to zero beforehand; this probably won't do anything, which would confirm that something's wrong with array[13]. What is the actual byte in the file? For example:
In my case it really is zero, but it never hurts to double-check.Code:$ hexdump test.bmp | head -n 1 0000000 4d42 647a 0000 0000 0000 007a 0000 006c
dwk
Seek and ye shall find. quaere et invenies.
"Simplicity does not precede complexity, but follows it." -- Alan Perlis
"Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
"The only real mistake is the one from which we learn nothing." -- John Powell
Other boards: DaniWeb, TPS
Unofficial Wiki FAQ: cpwiki.sf.net
My website: http://dwks.theprogrammingsite.com/
Projects: codeform, xuni, atlantis, nort, etc.
Here is the code;Thats the basis of the code - the struct can be seen on the previous page, named header (or maybe FILEHEADER). As mentioned works fine on pc though strangely produces a different value for imagedataoffset. Thanks again for your assistance.Code:char filename[20]; FILE *image; header data; unsigned char array[13]; printf("Enter File Name: \n"); scanf("%s", &filename); image = fopen(filename, "rb" ); fread(array, 1, 14, image); data.fileMarker1 = array[0]; data.fileMarker2 = array[1]; data.bfSize = array[2] + (array[3] << 8) + (array[4] << 16) + (array[5] << 24); data.unused1 = array[6] + (array[7] << 8); data.unused2 = array[8] + (array[9] << 8); data.imageDataOffset = array[10] + (array[11] << 8) + (array[12] << 16) + (array[13] << 24);
[QUOTE=christop;1122134]These three lines are a buffer overflow. array[13] does not exist. It is one char past the end of the array.
you're a legend! thanks so much for you're help!