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.