C ++の符号付き整数に16進数文字列に変換します
質問
私はC ++で32ビット符号付き整数に16進文字列に変換します。
ですから、例えば、私は、16進文字列「fffefffe」を持っています。 -65538:このバイナリ表現は、この符号付き整数表現である11111111111111101111111111111110.あります。
私はC ++でこの変換をどのように行うのですか?また、これは非負の数のために働く必要があります。例えば、バイナリで00000000000000000000000000001010、小数で10。16進文字列「0000000A」
解決
使用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標準では、あなたが利用することができ、いくつかの新しいユーティリティ関数があります!具体的には、「文字列の数を」関数の家族がある(ます。http:// EN .cppreference.com / W / CPP /文字列/の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
と私の手の両方が1ヘクス列にうまく対処していないロール。手動ヘクスへの入力ストリームを設定し、上記の溶液は、それがうまく処理します。
ブーストとしてこれを行うにはいくつかのものを持っていますだけでなく、同様の機能をチェックするいくつかの素晴らしい誤差を有しています。あなたはこのようにそれを使用することができます:
try {
unsigned int x = lexical_cast<int>("0x0badc0de");
} catch(bad_lexical_cast &) {
// whatever you want to do...
}
あなたはブーストを使用してのように感じていない場合は、ここにはエラーチェックを行わない字句キャストのライトバージョンがあります:
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");
他のヒント
CおよびC ++の両方で動作する方法については、あなたが標準ライブラリ関数strtolは()を使用して検討する必要があります。
#include <cstdlib>
#include <iostream>
using namespace std;
int main() {
string s = "abcd";
char * p;
long n = strtol( s.c_str(), & p, 16 );
if ( * p != 0 ) { //my bad edit was here
cout << "not a number" << endl;
}
else {
cout << n << endl;
}
}
アンディ・ブキャナン、限りC ++にこだわりが行くように、私はあなたを気に入って、私はいくつかの改造を持っています:
template <typename ElemT>
struct HexTo {
ElemT value;
operator ElemT() const {return value;}
friend std::istream& operator>>(std::istream& in, HexTo& out) {
in >> std::hex >> out.value;
return in;
}
};
タグのように使用
uint32_t value = boost::lexical_cast<HexTo<uint32_t> >("0x2a");
あなたはint型ごとに1 IMPLを必要としません。 このその方法
strtoul
との作業の例は次のようになります。
#include <cstdlib>
#include <iostream>
using namespace std;
int main() {
string s = "fffefffe";
char * p;
long n = strtoul( s.c_str(), & p, 16 );
if ( * p != 0 ) {
cout << "not a number" << endl;
} else {
cout << n << endl;
}
}
strtol
はstring
にlong
を変換します。私のコンピュータnumeric_limits<long>::max()
で0x7fffffff
を与えます。明らかにそれ0xfffefffe
は0x7fffffff
よりも大きくなります。だから、strtol
リターンは、希望値の代わりにMAX_LONG
。 strtoul
はstring
は、それはだunsigned long
に変換し、なぜこのような場合ではありません溢れています。
[OK]を、strtol
はconvertation前に入力された文字列ではないとして、32ビット符号付き整数を検討しています。 strtol
おかしいサンプルます:
#include <cstdlib>
#include <iostream>
using namespace std;
int main() {
string s = "-0x10002";
char * p;
long n = strtol( s.c_str(), & p, 16 );
if ( * p != 0 ) {
cout << "not a number" << endl;
} else {
cout << n << endl;
}
}
コンソールで-65538
プリント上記コード
ここで私が他の場所に簡単で、作業方法です
string hexString = "7FF";
int hexNumber;
sscanf(hexString.c_str(), "%x", &hexNumber);
あなたが値を受け取るために、符号なし長整数/ long整数を使用して好むかもしれないことに注意してください。 別のノート、c_str()関数は、ただのconst char型へ::文字列* STDに変換します。
準備*あなたがconstの文字を持っているのであれば、以下のようにちょうど[私も大きな進数の符号なしlong変数の使用方法を示しています、直接その変数名を使用して先に行きます。 ]文字列の代わりに*のconst char型を有する場合に、それを混同しないでください。
const char *hexString = "7FFEA5"; //Just to show the conversion of a bigger hex number
unsigned long hexNumber; //In case your hex number is going to be sufficiently big.
sscanf(hexString, "%x", &hexNumber);
これは(あなたがあなたの必要性につき、適切なデータ型を使用して)だけで完全に正常に動作します。
私は今日、同じ問題を抱えていた、ここで私は、私は>
<のlexical_castを保つことができ、それを解決した方法ですtypedef unsigned int uint32;
typedef signed int int32;
class uint32_from_hex // For use with boost::lexical_cast
{
uint32 value;
public:
operator uint32() const { return value; }
friend std::istream& operator>>( std::istream& in, uint32_from_hex& outValue )
{
in >> std::hex >> outValue.value;
}
};
class int32_from_hex // For use with boost::lexical_cast
{
uint32 value;
public:
operator int32() const { return static_cast<int32>( value ); }
friend std::istream& operator>>( std::istream& in, int32_from_hex& outValue )
{
in >> std::hex >> outvalue.value;
}
};
uint32 material0 = lexical_cast<uint32_from_hex>( "0x4ad" );
uint32 material1 = lexical_cast<uint32_from_hex>( "4ad" );
uint32 material2 = lexical_cast<uint32>( "1197" );
int32 materialX = lexical_cast<int32_from_hex>( "0xfffefffe" );
int32 materialY = lexical_cast<int32_from_hex>( "fffefffe" );
// etc...
(私はあまり嫌な方法を探していたときに、このページを発見: - )
乾杯、 ます。
これは私のために働いてます:
string string_test = "80123456";
unsigned long x;
signed long val;
std::stringstream ss;
ss << std::hex << string_test;
ss >> x;
// ss >> val; // if I try this val = 0
val = (signed long)x; // However, if I cast the unsigned result I get val = 0x80123456
別の方法
using namespace System;
template <typename NUM>
NUM hexstr2num(String^ h)
{
NUM v=0;
String^ k=L"0123456789ABCDEF";
short l=h->Length;
char off;
h=h->ToUpper();
if(h->Substring(0,1)!=L"H")
{if(h->Substring(0,2)==L"0X") off=2;}
else
{off=1;}
if(!off) throw;
char dx=0;
for(int i=l;i>off;i--)
{
if((dx=k->IndexOf(h->Substring(i-1,1)))>=0)
{v+=dx<<((l-i)<<2);}
else
{throw;}
}
return v;
}