我正在寻找一种使用流从文本文件中读取十六进制值的简单方法。我使用“C ++十六进制读取流0x”搜索了Stack Overflow,大多数响应是关于将十六进制写为文本或以十六进制值读取而没有“0x”前缀。这个问题是关于读取十六进制数,在一次操作中将“0x”前缀作为数字。
我的方法:
unsigned char byte;
std::istringstream sample("0xce");
sample >> std::hex >> byte;
从第一个字符开始,byte
包含'0'(0x30)。
'strtol`函数处理转换,但需要读取数据,转换为C风格的字符串。
我正在重载类中的operator>>
以读取逗号分隔值(CSV)文本文件。以下是数据文件的示例:
1,-4.93994892,0xa5,8,115.313e+3,
2,-4.93986238,0xc0,8,114.711e+3,
3,-4.93977554,0xc2,8,114.677e+3,
我的提取方法:
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;
}
我需要使用std::setw
吗?
编辑1:
我在Windows 7,64位平台上使用Visual Studio 2010 Premium。
答案 0 :(得分:7)
解决方案是使用unsigned int
读取值,然后转换为unsigned char
:
unsigned int value;
inp >> hex >> value;
unsigned char byte;
byte = value & 0xFF;
我想有一些导致问题的类型unsigned char
。
任何C ++语言律师都可以引用描述此行为的部分吗?
答案 1 :(得分:0)
问题是m_byte
成员Csv_Entry
的数据类型。在对输入数据进行输入流提取时,它会将0
解释为有效值,然后将x
解释为分隔符,从而丢弃流中的其余值 - 萃取。如果您将Csv_Entry::m_byte
成员更改为unsigned int
,则问题就会消失,并使用std::hex
正确解释十六进制值。
顺便说一句,由于您的所有成员都是公开的,您也可以将Csv_Entry
作为结构,但这里有一些使用您的输入数据的示例工作代码:http://ideone.com/H7NG1
您会注意到输出端,我只需要包含std::hex
和std::showbase
即可正确打印十六进制值。
答案 2 :(得分:0)
Thomas Matthews对。您必须从unsigned int
转换为unsigned char
。
如果您方便使用C函数scanf/printf
,您会发现它们的行为相似。但是我认为它们对于这种情况更具描述性。
//%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'
所以我的观点是你可以读取十六进制整数或读取字符,但是你试图“读取字符中的十六进制整数”。 stdlib开发人员的特定情况)