假设我有一个包含十六进制数字的字符串,其中每2个十六进制数字表示ASCII集中的字符,我需要将包含十六进制数字的字符串转换回其等效字符
我在这段代码中找到了我想要的东西: -
#include <algorithm>
#include <stdexcept>
std::string hex_to_string(const std::string& input)
{
static const char* const lut = "0123456789ABCDEF";
size_t len = input.length();
if (len & 1) throw std::invalid_argument("odd length");
std::string output;
output.reserve(len / 2);
for (size_t i = 0; i < len; i += 2)
{
char a = input[i];
const char* p = std::lower_bound(lut, lut + 16, a);
if (*p != a) throw std::invalid_argument("not a hex digit");
char b = input[i + 1];
const char* q = std::lower_bound(lut, lut + 16, b);
if (*q != b) throw std::invalid_argument("not a hex digit");
output.push_back(((p - lut) << 4) | (q - lut));
}
return output;
}
我是C ++的新手,我可以理解直到部分输出.push_back(((p - lut)&lt;&lt;&lt;&lt; 4)|(q - lut));
假设字符串包含十六进制值72(表示ACSII中的字符'r'),并且在输出字符串的push_back操作之前,p和lut的值将为: -
p =“789ABCDEF”
lut =“0123456789ABCDEF”
但是,此函数中的(p - lut)结果为7。我不太明白这是怎么发生的。??
答案 0 :(得分:0)
考虑以下情况,打印出'A'(0x41为A)。
std::string str="41";
std::stringstream ss;
ss << std::hex << str;
int i;
ss >> i;
std::cout << static_cast<char>(i);
答案 1 :(得分:0)
那是指针算法。
p
的值不是"7890ABCDEF"
。而是存储在p
中的地址中的内容。由于p
是指针,因此值是一个地址。
lut
指向元素0,p
指向同一数组中的元素7。因此p - lut
为7。
对于任何n
,p + n
与&p[n]
相同,即n
- 元素的地址。在这里反过来使用这个事实。
答案 2 :(得分:0)
我会尝试分解正在发生的事情
output.push_back(((p - lut) << 4) | (q - lut));
假设“72”
我们做地址的差异,以获得索引
p - lut = 7
q - lut = 2
对十六进制代码的左侧部分应用4位左移
7 << 4 == 0x70
二进制或合并两个
0x70 | 0x02 == 0x72