我需要将十六进制字符串转换为二进制,然后将这些位传递给不同的变量。
例如,我的输入是: std :: string hex =“ E136”;
如何将字符串转换为二进制输出1110 0001 0011 0110? 之后,我需要将位0传递给变量A,将位1-9传递给变量B,将位10-15传递给变量C。
预先感谢
答案 0 :(得分:1)
如何转换字符串[...]?
以结果值null开头,然后为每个字符(首先开始,表示最高有效)确定其值(在[0:15]范围内),将到目前为止收到的结果乘以16,然后将当前值加重视。对于您给定的示例,这将导致
(((0 * 16 + v('E')) * 16 + v('1')) * 16 + v('3')) + v('6')
有一些标准的库函数可以为您完成这些工作,例如std::strtoul
:
char* end;
unsigned long value = strtoul(hex.c_str(), &end, 16);
// ^^ base!
结束指针,可用于检查是否已读取整个字符串:
if(*char == 0)
{
// end of string reached
}
else
{
// some part of the string was left, you might consider this
// as error (could occur if e. g. "f10s12" was passed, then
// end would point to the 's')
}
如果您不关心结束检查,则可以只通过nullptr
。
以后不要转换回字符串,可以通过屏蔽(&
)和移位(>>
)来获得所需的值,例如。 g获得位[1-9]:
uint32_t b = value >> 1 & 0x1ffU;
处理整数要比处理字符串有效得多。仅当您要打印最终结果 时, then 才转换回字符串(如果使用std::ostream
,{{1 }}已经为您完成工作...)。
答案 1 :(得分:0)
在处理此示例时,我意识到我提出了错误的建议:
std::setbase(2)
不起作用。哎哟! (SO: Why doesn't std::setbase(2) switch to binary output?)
要将数字转换为带有二进制数字的字符串,必须使用其他方法。我做了这个小样本。尽管也考虑了位的分离,但我的主要重点是基于不同基数的输出(恕我直言,这是另一个答案):
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <string>
std::string bits(unsigned value, unsigned w)
{
std::string text;
for (unsigned i = 0; i < w || value; ++i) {
text += '0' + (value & 1); // bit -> character '0' or '1'
value >>= 1; // shift right one bit
}
// text is right to left -> must be reversed
std::reverse(text.begin(), text.end());
// done
return text;
}
void print(const char *name, unsigned value)
{
std::cout
<< name << ": "
// decimal output
<< std::setbase(10) << std::setw(5) << value
<< " = "
// binary output
#if 0 // OLD, WRONG:
// std::setbase(2) is not supported by standard - Ouch!
<< "0b" << std::setw(16) << std::setfill('0') << std::setbase(2) << value
#else // NEW:
<< "0b" << bits(value, 16)
#endif // 0
<< " = "
// hexadecimal output
<< "0x" << std::setw(4) << std::setfill('0') << std::setbase(16) << value
<< '\n';
}
int main()
{
std::string hex = "E136";
unsigned value = strtoul(hex.c_str(), nullptr, 16);
print("hex", value);
// bit 0 -> a
unsigned a = value & 0x0001;
// bit 1 ... 9 -> b
unsigned b = (value & 0x03FE) >> 1;
// bit 10 ... 15 -> c
unsigned c = (value & 0xFC00) >> 10;
// report
print(" a ", a);
print(" b ", b);
print(" c ", c);
// done
return 0;
}
输出:
hex: 57654 = 0b1110000100110110 = 0xe136
a : 00000 = 0b0000000000000000 = 0x0000
b : 00155 = 0b0000000010011011 = 0x009b
c : 00056 = 0b0000000000111000 = 0x0038
关于位操作:
二进制按位和运算符(&
)用于将所有意外位设置为0。第二个值可以理解为掩码。如果我使用了二进制数,则将更加明显,但是C ++不支持此功能。十六进制代码几乎与十六进制数字一样好,它始终表示相同的4位模式。 (因为16 = 2 4 )经过一段时间的练习,您通常会学会“查看”十六进制代码中的位。
关于右移(>>
),我不太确定。 OP不需要将位移动到某个位置–只是必须将它们分成不同的变量。因此,这些右移可能已过时。
因此,这个似乎微不足道的问题(对我而言)带来了令人惊讶的启示。