tags:

views:

327

answers:

3

I have a bitmap image that I am parsing and I need to be able to open the file and store the first unsigned short.

I tried to accomplish this using FILE and fscanf() but fscanf() always fails and returns 0 (number of items successfully read).

FILE *pFile = fopen ( fileName->c_str() , "r" );

if ( pFile == NULL )
{
    cerr << "couldn't open file ; exiting..." << endl;
    exit(0);
}

unsigned short seed;
fscanf (pFile, "%hu", &seed);

Does anyone know of another approach I could take (possibly ifstream?) or maybe could just give me some pointers? Any help would be greatly appreciated.

Thank you.

A: 
std::ifstream input("inputfile.txt");  
unsigned short value;  
input >> value;
Stephen Newell
+2  A: 

Ahh! No! fscanf is for text! %hu will look for strings like "1234" in a file, not the actual bytes!

Use fread.

E.g.

FILE *fp = fopen("foo", "rb");
unsigned short x;
fread(&x, sizeof x, 1, fp);

Indeed, watch out for endianness, and open the file in binary. "rb" to be safe on Windows. Check return codes, etc.

Alex
+11  A: 

Don't use the formatted functions like *scanf; they expect character representations of the data, the complement of the *printf functions which translate values into character representations.

unsigned val;
f = fopen (filename, "rb");
if (fread (&val, 1, sizeof (val), f) != sizeof (val))
    // error

The biggest caveat of this is how the file was written. If the endianness of the writer is different than the computer this runs on, then explicit endian code should be used instead:

unsigned val;
unsigned char buf[2];
f = fopen (filename, "rb");
if (fread (buf, 1, sizeof (buf), f) != sizeof (buf))
    // error
else {
//  val = (buf [0] << 8) | buf [1];   // for big endian written file
    val = (buf [1] << 8) | buf [0];   // for little endian written file
}
wallyk
That should be `unsigned char buf[2];`, and `sizeof buf` instead of `sizeof(val)`.
caf
Please, God, take out the #ifdef so I can upvote your solution. The byte order of the file should be known, not determined by a compile-time preprocessor parameter...
Norman Ramsey
Thanks for the feedback—I agree.
wallyk
Just store your file in network byte order and use htons and ntohs to convert it for you. These have the added advantage of being automagically defined for you at compile time to "do the right thing".
Southern Hospitality