1. ホーム
  2. c++

[解決済み] C++ 16進文字列を符号付き整数に変換する

2022-05-12 19:18:23

質問

C++で16進文字列を32ビット符号付き整数に変換したいのですが、どうすればよいですか?

例えば、私は16進文字列 "fffefffe" を持っているわけです。 これを 2 進法で表現すると、1111111111111011111111111110 となります。 これを符号付き整数で表現すると、-65538 となります。

C++でこの変換を行うにはどうしたらよいでしょうか。 これは、非負の数に対しても動作する必要があります。 例えば、16進数の文字列 "0000000A"は、2進数では0000000000000000001010、10進数では10になります。

どのように解決するのですか?

使用 std::stringstream

unsigned int x;   
std::stringstream ss;
ss << std::hex << "fffefffe";
ss >> x;

次の例では -65538 を結果として出力します。

#include <sstream>
#include <iostream>

int main() {
    unsigned int x;   
    std::stringstream ss;
    ss << std::hex << "fffefffe";
    ss >> x;
    // output it as a signed type
    std::cout << static_cast<int>(x) << std::endl;
}

新しい C++11 標準では、利用できる新しいユーティリティ関数がいくつかあります!具体的には、"string to number" 関数のファミリ ( http://en.cppreference.com/w/cpp/string/basic_string/stol http://en.cppreference.com/w/cpp/string/basic_string/stoul ). これらは本質的にCの文字列から数値への変換関数の薄いラッパーです。 std::string

ですから、新しいコードに対する最も単純な答えは、おそらく次のようになります。

std::string s = "0xfffefffe";
unsigned int x = std::stoul(s, nullptr, 16);


注意 以下は私のオリジナルの回答ですが、編集が言うように完全な回答ではありません。機能的な解決策としては、行の上にコードを貼り付けてください :-)。

それは lexical_cast<> はストリーム変換のセマンティクスを持つように定義されています。悲しいことに、ストリームは "0x" という記法を理解しません。そのため、両方の boost::lexical_cast も私の手によるものも、16進文字列をうまく扱えない。手動で入力ストリームを 16 進数に設定する上記のソリューションは、それをうまく処理します。

Boostにはいくつかのものがあります。 があり、エラーチェックの機能もあります。こんな風に使うことができます。

try {
    unsigned int x = lexical_cast<int>("0x0badc0de");
} catch(bad_lexical_cast &) {
    // whatever you want to do...
}

boostを使う気がしないのであれば、エラーチェックをしないレキシカルキャストのライトバージョンを紹介します。

template<typename T2, typename T1>
inline T2 lexical_cast(const T1 &in) {
    T2 out;
    std::stringstream ss;
    ss << in;
    ss >> out;
    return out;
}

というように使うことができます。

// though this needs the 0x prefix so it knows it is hex
unsigned int x = lexical_cast<unsigned int>("0xdeadbeef");