0

假设我有一个包含十六进制数字的字符串,其中每 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++ 比较陌生,我可以理解直到部分 output.push_back(((p - lut) << 4) | (q - lut));
假设字符串包含 72 的十六进制值(表示 ACSII 中的 char 'r')并且就在输出字符串的 push_back 操作之前,p 和 lut 的值将是:- p = "789ABCDEF" lut = "0123456789ABCDEF "

但是,这个函数中的 (p - lut) 结果是 7。我不太明白这是怎么发生的。??

4

3 回答 3

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);
于 2012-05-04T15:09:30.583 回答
0

那是指针算法。

p不是"7890ABCDEF"。_ 而是存储在p. 因为p是指针,所以它的是地址。

lut指向元素 0,p指向同一数组中的元素 7。因此p - lut为 7。

对于任意n,p + n与 相同&p[n],即n第-个元素的地址。在这里,这个事实被反过来使用。

于 2012-05-04T15:16:08.570 回答
0

我会尝试分解正在发生的事情

 output.push_back(((p - lut) << 4) | (q - lut));

假设“72”

我们做地址的差异,得到索引

p - lut = 7 
q - lut = 2

对十六进制代码的左侧部分应用 4 位左移

7 << 4 == 0x70

二进制或合并两者

0x70 | 0x02 == 0x72
于 2012-05-04T15:25:40.073 回答