简体   繁体   中英

Read hex text format 0x from stream

I'm looking for a simple method to read a hex value from a text file using streams. I searched Stack Overflow using "C++ hex read stream 0x" and most of responses were about writing hex as text or reading in hex values without the "0x" prefix. This question is about reading the hex number, with "0x" prefix as a number in one operation.

My method:

unsigned char byte;
std::istringstream sample("0xce");
sample >> std::hex >> byte;

Ends up with byte containing '0' (0x30) from the first character.

The 'strtol` function handles the conversion, but requires reading the data, converting to C-style string.

I'm overloading the operator>> in a class to read a comma separated value (CSV) text file. Here is a sample of the data file:

1,-4.93994892,0xa5,8,115.313e+3,
2,-4.93986238,0xc0,8,114.711e+3,
3,-4.93977554,0xc2,8,114.677e+3,

My extraction method:

class Csv_Entry
{
public:
    friend std::istream& operator >>(std::istream& inp, Csv_Entry& ce);
    unsigned int    m_index;
    double      m_time;
    unsigned char   m_byte;
    unsigned int    m_data_length;
    double      m_bit_rate;
};

std::istream&
operator >> (std::istream& inp, Csv_Entry& ce)
{
    char    separator;
    inp >> ce.m_index;
    inp >> separator;
    inp >> ce.m_time;
    inp >> separator;
    inp >> std::hex >> ce.m_byte;
    inp >> separator;
    inp >> ce.m_data_length;
    inp >> separator;
    inp >> ce.m_bit_rate;
    inp.ignore(10000, '\n');
    return inp;
}

Do I need to use std::setw ?

Edit 1:
I'm using Visual Studio 2010 Premium on Windows 7, 64-bit platform.

A solution is to read the value using an unsigned int then convert to unsigned char :

unsigned int value;
inp >> hex >> value;
unsigned char byte;
byte = value & 0xFF;

I guess there is something about the type unsigned char that is causing the issue.

Any C++ language lawyers can quote a section that describes this behavior?

The problem is the data-type for your m_byte member of Csv_Entry . When going through input-stream extraction for your input data, it's interpreting the 0 as a valid value, then interpreting the x as a separator, and therefore throwing off the rest of the values in the stream-extraction. If you change your Csv_Entry::m_byte member to an unsigned int , the problem goes away, and it interprets the hex-value properly using std::hex .

BTW, since all your members are public, you might as well make Csv_Entry a structure, but here is some sample working code using your entry data: http://ideone.com/H7NG1

You'll notice on the output side, I only need to include std::hex and std::showbase to get the hex values to print correctly.

Thomas Matthews right. You have to convert from unsigned int to unsigned char .

If you are convenient with C-functions scanf/printf you'll notice that they behave similar. But they are more descriptive for this situations I think.

//%X specifies that we trying read integer in format 0x123FFF
//%c specifies that we trying read character
//0xABC is input string

unsigned char hex;
sscanf("0xABC", "%X", &hex); // error because not enough memory allocated
                             // by address &hex to store integer

unsigned char hex;
sscanf("0xABC", "%c", &hex); // reads only one character '0'

So my point is that you can either read a hexadecimal integer or read character, but you trying to "read hexadecimal integer in character". So specific case for stdlib developers )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM