Thread: Fun with reading hex

  1. #1
    I am me, who else?
    Join Date
    Oct 2002
    Posts
    250

    Fun with reading hex

    Hopefully this is a simple question to answer. I can't seem to find anything via searches, but perhaps I do not know exactly what to look for.

    I am reading a file, in hex, and converting the values as I go.

    For instance a file might have (in hex):

    2345 6789 0000 0004 0000 0001 0000 0001 0000 0008 0000 000C
    0100 0000 ... and so forth.

    Now in a hex editor I can view this just fine, but as I interpret it with my own program, interesting things start to happen.

    I read byte by byte through the file using std::iostream.

    Code:
    std::ifstream in;
    in.open( "thefile", ios::binary );
    Then I make sure the file is open:

    Code:
    char *temp = new char[4];
    
    if( in.is_open() )
    {
      //read 4 bytes then analyze
      in.read( temp, 4 );
     //convert to hex
     CString hex;
     hex.Format( "%X%X%X%X", temp[0], temp[1], temp[2], temp[3] );
     //do whatever I wish with it, and move on
     ...
    }
    I realize this is not the best way of reading it, but it worked for me for a while, and now I hit a wall.

    Say when reading the line I listed above, 2345 6789 ...
    I can read 2345 6789 fine, but when I hit 0000 0004, it chops the first 0000 off when I read the value, and when I format. Then when I hit the second line, instead of getting the value of 0100 0000, I get 1000, which makes no sense. Perhaps I am just not quite understanding what I am doing here, but any pointers would be helpful. Thanks!

  2. #2
    Hardware Engineer
    Join Date
    Sep 2001
    Posts
    1,398
    I haven't seen the CString hex; hex.Format() technique before, so I can't comment on that...

    But I have used:
    cout << hex << x << "\t Hex" << endl;

    And, I've used sprintf() to make an ASCII string that "looks like" hex, which might be more similar to what you are trying to do.

    You might have an issue with the size of chars and ints, or a big-endian little-endian issue. Try displaying the "regular" decimal values, just to make sure that the "numbers" agree with the hex editor.

    I suspect you already know this: If you don't have a hex calclulator, The Windows calculator can do hex to dicimal conversions in the "scientific" mode.
    Last edited by DougDbug; 02-16-2006 at 07:01 PM.

  3. #3
    I am me, who else?
    Join Date
    Oct 2002
    Posts
    250
    hmmm well basically what I am doing is taking the values from the file, reading them in as hex values, and translating them as I go.

    Supposedly CString can format hex using %X, and so far, it seems to be working, but kinda screws up after a while. I do not know if thats the best way to do it. It is supposed to be equivalent of the sprintf() way, but who knows for sure. I'll see what sprintf does for me, and comment back on that later. Thanks for the suggestions!

    Edit:

    Yeah I've played around with it, and used hexworkshop to check the endian-ness. Problem is, it cuts the first 2 bytes off sometimes, especially when they are 0's which I sort of understand, but when it changes the value from 0100 0000 (1.6ish million) to 1000 (4096) there's a problem . Why its doing that is still a mystery, I display the full file in hex, and even there it chops the extra 0's off.
    Last edited by dpro; 02-16-2006 at 07:11 PM.

  4. #4
    30 Helens Agree neandrake's Avatar
    Join Date
    Jan 2002
    Posts
    640
    You need to pad out so it displays 4 digits for each %X every time. I wrote a basic hex viewer in C a long time ago, and I would have to rummage through some backup disks in order to find it, but I used printf and had to force padding. Off the top of my head, try this:
    Code:
    hex.Format( "%1X%1X%1X%1X", temp[0], temp[1], temp[2], temp[3] );
    The 1 should be the forced padding width.

    But your method doesn't seem quite right to me. Unless you are trying to accomplish something different.

    Code:
    char temp = 0;
    
    if( in.is_open() )
    {
      //read 4 bytes then analyze
      in.read( temp, 1 );
     //convert to hex
     CString hex;
     hex.Format( "%2X ", temp );
     //do whatever I wish with it, and move on
     ...
    }
    That may not be exactly right (or exactly wrong depending on your goal). I don't know the in.read() function off hand and you may have to change temp back to a pointer. Unless you need to read in 4 bytes at a time, but you could create an array queue that holds like 16 bytes of the file at a time. I'm just throwing ideas out there though. But for my first example, you may want to change the 1 to 2 and put a space in between each %2X. That should print out 4 bytes at a time.
    Last edited by neandrake; 02-16-2006 at 10:30 PM.
    Environment: OS X, GCC / G++
    Codes: Java, C#, C/C++
    AOL IM: neandrake, Email: neandrake (at) gmail (dot) com

  5. #5
    Registered User
    Join Date
    Feb 2006
    Posts
    155
    "2345"


    if thats hex then that is 1 word(2bytes or a short) not 1 byte.


    and do u know about the little endian ?
    2345 4567
    if i read by using char
    i get 23 45 45 67
    if i read by using short i get
    4523 6745

    if i read but using int i get
    67454523
    Last edited by qqqqxxxx; 02-17-2006 at 12:44 AM.

  6. #6
    I am me, who else?
    Join Date
    Oct 2002
    Posts
    250
    Thanks for the input, you bring up some good points neandrake. I have verified the endianess of my machine. 2345 6789, was actually something different, the value in hex is 2345 6789 this is the only hex number that is written.

    Basically I will give some more tries to this, however I am not sure what you mean neandrake, what I need to do is get 4 bytes at a time, hence the in.read( temp, 4 ); So I think that is right, but if it is wrong, then I would like to know

  7. #7
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    The correct format string for a single byte is "%02X", but I'm not sure if CString's Format() supports that. Just try.

    Oh, and you ought to make temp unsigned. And there's no reason to allocate it dynamically.
    Code:
    unsigned char temp[4];
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  8. #8
    I am me, who else?
    Join Date
    Oct 2002
    Posts
    250
    Excellent CornedBee, that seemed to fix it right up thanks a lot!

    That is true, I had written it, and wanted to get it done and did not feel like changing it back to non-dynamically allocated memory. Thanks again!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 6
    Last Post: 11-11-2006, 02:10 PM
  2. Replies: 11
    Last Post: 03-24-2006, 11:26 AM
  3. Replies: 3
    Last Post: 01-23-2006, 07:25 PM
  4. write to hex, is it possible?
    By keithmolo in forum C++ Programming
    Replies: 12
    Last Post: 07-30-2003, 02:27 PM