Search code examples
c++linuxfilebmp

Reading Fileheader of a BMP with fread()


I am working on Linux trying to load the header of a BMP. I've looked at the header and should be getting "BM" for the first two characters of the file. The code I've been using:

FILE* fp = fopen(filename, "r");
if(!fp)
{
    std::cout << "Unable to open file : " << filename << std::endl;
    return NULL;
}

char* headerField = new char[2];
fread(headerField, 2, sizeof(char), fp);
std::cout << headerField << std::endl;

if(strcmp(headerField, "BM")){
    delete [] headerField;
    std::cout << "File is not a bitmap" << std::endl;
    fclose(fp);
    return NULL;
}
else{
    std::cout << "Well done!" << std::endl;
}

The output I'm getting is BM followed by a random extra character, "BM7", "BMF", "BM*"... As I understand it, fread() should read in (in this case) two characters worth of data, so where is this extra character coming from?


Solution

  • You are heavily mixing c and c++, I think this is half of the reason why you got into the bug in the 1st place.

    Now, in c strings are called null-terminated strings of characters for a reason. The null character \0 is an end of string delimiter. What you are doing is reading two bytes into the headerField. So in memory it looks like:

    | B | M | garbage | garbage | garbage |

    str family, and other routines expect the char* strings to have \0 at the end. So the strcmp, and printing does not stop after M but run into the wild. A proper 2 character c-style string should occupy 3 bytes and look like:

    | B | M | 0 | garbage | garbage |

    How you make it happen I leave up to you.

    I would rewrite the code into a proper c++ personally.