0

16 進数を含む文字列があり、16 進数の 2 桁ごとに ASCII セットの文字を表し、16 進数を含む文字列を同等の文字に変換する必要があるとします。

私はこのコードで探していたものを見つけました:-

#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 の 16 進数値 (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 です。

の場合np + 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

16 進コードの左部分に 4 ビット左シフトを適用する

7 << 4 == 0x70

バイナリまたは2つをマージする

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