C ++将hexstring转换为有符号整数

我想在C ++中将hexstring转换为32位有符号整数。

所以,例如,我有hexstring“fffefffe”。 这个二进制表示是11111111111111101111111111111110.这个有符号整数表示是:-65538。

我如何在C ++中进行这种转换? 这也需要为非负数工作。 例如,hexstring“0000000A”,二进制为00000000000000000000000000001010,十进制为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更新。 在新标准中,您可以使用一些新的实用function! 具体来说,有一个“string到数字”函数( http://en.cppreference.com/w/cpp/string/basic_string/stol和http://en.cppreference.com/w/cpp/string/ basic_string / stoul )。 这些本质上是C的string到数字转换函数周围的薄包装,但知道如何处理std::string

所以,最新的代码最简单的答案可能是这样的:

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

注意:下面是我的原始答案,正如编辑说,不是一个完整的答案。 对于function解决scheme。 将代码粘贴在该行的上方:-)。


编辑:看来,因为lexical_cast<>被定义为具有stream转换语义。 不幸的是,stream不理解“0x”符号。 所以boost::lexical_cast和我的手滚动一个不能很好地处理hexstring。 上面的手动设置inputstream为hex的解决scheme将处理它就好了。

Boost有一些东西可以做到这一点,它也有一些很好的错误检查function。 你可以像这样使用它:

 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 ++而言,我喜欢你的,但我有几个mod:

 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"); 

这样你不需要每个inttypes一个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; } } 

strtolstring转换为long 。 在我的电脑上, numeric_limits<long>::max()给出了0x7fffffff 。 显然, 0xfffefffe大于0x7fffffff 。 所以strtol返回MAX_LONG而不是想要的值。 strtoulstring转换为unsigned long ,这就是为什么在这种情况下没有溢出。

好吧, strtol正在考虑inputstring不是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

下面是我在其他地方find的一个简单的工作方法:

 string hexString = "7FF"; int hexNumber; sscanf(hexString.c_str(), "%x", &hexNumber); 

请注意,您可能更喜欢使用无符号长整数/长整数来接收值。 另外需要注意的是,c_str()函数只是将std :: string转换为const char *。

所以如果你有一个const char *就可以了,直接使用这个variables名就可以了,如下图所示[我也展示了一个更大的hex数的无符号长variables的用法。 不要把它与const char *而不是string混淆]:

 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); 

这工作得很好(只要你根据你的需要使用适当的数据types)。

今天我有同样的问题,这是我如何解决它,所以我可以保留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... 

(find这个页面,当我正在寻找一个不太烂的方式:-)

干杯,答:

这对我工作:

 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<<((li)<<2);} else {throw;} } return v; }