Pwrcdr87 Pwrcdr87 - 3 years ago 162
C Question

Parsing bytes of a bitmap header and saving with file pointers

I'm working on my first project in my first C Programming class and am getting lost with pointers. We are to alter bitmaps in various ways and I'm having a hard time with understanding how I can use file pointers to grab byte data I want to use and manipulate. I know the bitmap file header and DIB header structure as well as the byte offset for the values that comprise them. However, I'm having difficulty understanding how to save each of those values for use later with file pointers. Since this is for a project I don't want to ask for too much help. Here is my code so far and various means I've attempted to capture parts of the header:

int main(int argc, const char * argv[]){
FILE *fp;
char buff[2]; //only trying '2' to try and capture 'BM' at start of file.
fp = fopen(argv[1], "r+b");
fseek(fp, 0, SEEK_END);
long fsize = ftell(fp);
rewind(fp);

// this is where I test what to do but can't get it correct
unsigned short filetype = fgetc(fp);
printf("First letter of filetype %c\n", filetype); //prints 'B' which is awesome

//Now I do not understand how to capture both the 'BM'.
//I've changed to use the fread as follows:
fread(buff, sizeof(char), 2, fp);
printf("Captured bytes with fread %s\n", buff) //this prints 4 char's and not 2?

fclose(fp);
return 0;
}


I also tested a simple while loop to traverse the entire file and print each character until
EOF
is encountered using
fgetc
which worked. So I'm assuming that with each call of
fgetc
it changes the location of the pointers current byte position to current position + 1.

I guess I'm not fully grasping how the file pointer can be used to save numerous bytes into a single stored variable. I've also tried
fseek
and
fgets
to no avail.

I'd appreciate any help and input I can get from the community here.

Answer Source

printf("%s", buff) prints the character pointed by buff and subsequent characters until it reaches a NUL character. Unfortunately, buff only contained B and M, so printf kept reading past the end of the array until it found a NUL. That's bad!

Replace

char buff[2];
fread(buff, sizeof(char), 2, fp);

with

char buff[3];
size_t num_read = fread(buff, sizeof(char), 3, fp);
buff[num_read] = 0;

Note that sizeof(char) is guaranteed to be 1.

Note that fgetc advanced the file pointer beyond the B, so you'll need to rewind it once more if you want the fread to read the B.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download