Raw binary data conversion

Dec 20, 2011 at 10:35pm
Hi there,

Ive tearing what little hair I have left out over this one and not sure where else to turn so created account here (after picking up so many tips over the years).

I am reading tag/data pairs from a binary file and all working fine except for values with tag data value of 242.

tag/data pairs are stored in vector of simple structs as follows:

1
2
3
4
5
struct TagData
{
int Tag;
int Data;
};


these are parsed and read in in pairs by loop that calls my GetNextTag function as follows:

 
GetNextTag (DLF, tmpTag.Tag, tmpTag.Data);


where DLF is delcared as binary ifstream...

ifstream DLF (Filename.c_str(), ios::in | ios::binary);

GetNextTag is, in full...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
bool DLogg_DataSet::GetNextTag (ifstream &DLF, int &tag, int &data)
{
char buffer_4b[4];
char buffer_1b[1];
DLF.read ((char*)&buffer_1b, 1);
tag = buffer_1b[0]; 
DLF.read ((char*)&buffer_4b, 4);
data = *(int*) buffer_4b;
//check for failures...
if (DLF.fail()) return false;
if (DLF.eof()) return false;
//thats all we check for, maybe more to check...
return true;
}


Now the issue I have is as follows

tag = buffer_1b[0]; ///TODO: this is reading in hec 0xF2 to int as -14 not 242...

I have run out of ideas and works for other tags but this is the highest number read in so must have something to do with this.

Throwing it out to the larger audience to see if there are any thoughts or glimmers of insperation?

Many thanks

John
Dec 20, 2011 at 10:40pm
try using unsigned char instead of char
Dec 20, 2011 at 10:50pm
Also, I have two (admittedly somewhat tangential) questions here.

1: Why are you using an array of size 1?

2: If your largest tag is one byte long, why not just use an unsigned char for your Tag member variable?

-Albatross
Last edited on Dec 20, 2011 at 10:51pm
Dec 20, 2011 at 11:05pm
You don't need to have temporary buffers for this. Just read to your data directly:

1
2
3
4
5
6
7
8
9
10
11
12
13
// note this only works for little endian systems -- but you're already doing endian specific stuff
//  so I assume it doesn't matter

bool DLogg_DataSet::GetNextTag (ifstream &DLF, int &tag, int &data)
{
  tag = 0;  // clear high bytes of tag
  DLF.read( (char*)(&tag), 1 );  // read it into tag directly.  No need to make a separate buffer
     // assumes little endian

  DLF.read( (char*)(&data), 4 );  // assumes sizeof(int) == 4, assumes file saved with system endianness

  // ... check for errors or whatever
}
Dec 21, 2011 at 9:49am
All, many thanks for the replies.

Peter87, Had tried this as thought it looked like the sign bit might be screwing things up but didn't work. However... will retry when back at PC (tmrw!!!).

Albtross, 1. Aide memoir and personal (possibly incorrect) style!! 2. Wanted it cast and stored as an int for use elsewhere in program.

Disch, Thanks that looks more compact. file not saved with system endianness though. Always little endian as file comes from external microprocessor.

Any more suggestions as to why F2 giving -14 and not 242???

Many thanks

JA

Dec 21, 2011 at 4:27pm
Because you were setting a signed bit in your read operation. Did you notice how |-14| + |242| = 256?

-Albatross
Dec 21, 2011 at 4:37pm
Hi albatross,

Did search at lunch earlier and came up with:

F2 == 11110010 so with signed bit:

-128+64+32+16+0+0+2+0=-14.... so must be something to do with this.

Thanks for the feedback and will have a mess around with it later and see if it is solved. Looks like peter has it but sure this didnt work for me and so dismissed it....

Kind regards

John
Dec 26, 2011 at 12:47am
Hi all,

Will mark as solved. Use of unsigned char in line 4 of my original post when reading in solved it. Many thanks for the feedback and merry christmas.

Festive Regards

John
Topic archived. No new replies allowed.