Reputation: 31
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define NBRCOLOURS 16
#define COLOURSIZE 8
typedef struct
{
char colours[COLOURSIZE];
}BITMAP;
//Main Function
void main(void)
{
int count, count2;
char bm_file[] = "C:\\Coding\\Bitmap Program\\Sample.bmp";
FILE *fptr;
char ch;
int i = 0;
BITMAP bm_data[NBRCOLOURS];
fptr = fopen(bm_file, "rb");
if (fptr != NULL)
{
while ((ch = fgetc(fptr)) != EOF)
{
printf("%02X ", ch);
if (!(++i % 16)) putc('\n', stdout);
}
}
fclose(fptr);
system("pause");
return;
}
I am using this code which I found mostly online to try and read the contents of a bitmap file as its hexadecimal values. For some reason, this code stops right at the end of the header, and unfortunately ultimately I need to count the number of times each colour appears so that I can figure out which occurs most and which occurs least.
If anyone could tell me why this code stops at the end of the header for the bitmap, or lead me towards being able to pull the rest of the hexadecimal data out of the file, I would really appreciate it.
Here is the hex code:
42 4D C6 00 00 00 00 00 00 00 76 00 00 00 28 00
00 00 0A 00 00 00 0A 00 00 00 01 00 04 00 00 00
00 00 50 00 00 00 12 0B 00 00 12 0B 00 00 10 00
00 00 10 00 00 00 FF 00 00 00 00 FF 00 00 00 00
42 00 5A 5A 84 00 00 00 FF 00 FF 00 FF 00 00 FF
FF 00 08 FF FF 00 5A FF FF 00 FF FF FF 00 FF FF
FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF FF
FF 00 FF FF FF 00 92 59 00 16 47 00 00 00 25 90
01 64 61 00 00 00 59 90 11 64 61 00 00 00 99 00
16 48 11 00 00 00 90 01 64 61 11 00 00 00 00 16
64 61 00 00 00 00 01 16 46 10 09 00 00 00 11 64
41 00 99 00 00 00 16 64 11 09 95 00 00 00 66 48
10 09 53 00 00 00
And here is what prints:
42 4D FFFFFFC6 00 00 00 00 00 00 00 76 00 00 00 28 00
00 00 0A 00 00 00 0A 00 00 00 01 00 04 00 00 00
00 00 50 00 00 00 12 0B 00 00 12 0B 00 00 10 00
00 00 10 00 00 00
Long post, I'm sorry. Any help is greatly appreciated.
Upvotes: 2
Views: 147
Reputation: 21542
The number before a format specifier in printf
, like %02X
only guarantees a minimum number of characters outputted, not a maximum. fgetc
returns an int
, not a char
. If the int
is negative two's complement then the entire bitstring representing the int will get printed, including the FF
bytes at the start. EOF
is not representable as a char
; only as an int
.
In your case we know that the file we're working with is small enough that loading the entire file into a buffer will probably succeed, so we can just use malloc
and free
instead:
#include <stdio.h>
#include <stdlib.h>
typedef unsigned char byte;
int main(int argc, char *argv[])
{
FILE *fp = fopen("C:\\Coding\\Bitmap Program\\Sample.bmp", "rb");
byte *buffer = NULL;
size_t len;
int i;
fseek(fp, 0, SEEK_END);
len = ftell(fp);
rewind(fp);
buffer = malloc(len);
if(!buffer)
{
perror("malloc");
exit(EXIT_FAILURE);
}
fread(buffer, 1, len, fp);
fclose(fp);
for(i = 0; i < len; i++)
{
if(i%16==0) putchar('\n');
printf("%.2X ", buffer[i]&0xFF);
}
free(buffer);
return 0;
}
Upvotes: 0
Reputation: 4704
fgetc returns an int, not a char. You can't represent EOF with a char, as all of the possible values of a char are valid. EOF is (I think) -1 represented as an int, or 0xfffffff, so if you read 0xff as a char it's the same as EOF.
Change this:
char ch;
to:
int ch;
Upvotes: 3