|
|
道上混的领结 · openssl库HMAC使用 ...· 1 月前 · |
|
|
打篮球的蛋挞 · 实验室简介-福州大学多尺度材料设计与应用实验室· 12 月前 · |
|
|
绅士的葡萄酒 · 关于mapStruct-高阶用法 - ...· 1 年前 · |
|
|
卖萌的皮带 · yolo5纸张卡片顶点检测,实现任意倾斜角度 ...· 1 年前 · |
|
|
大方的铁板烧 · Python脚本说 ...· 2 年前 · |
我想在C++中将十六进制字符串转换为32位有符号整数。
例如,我有一个十六进制字符串"fffefffe“。它的二进制表示是1111111111111010111111111111111111111110。它的带符号整数表示是:-65538。
如何在C++中执行此转换?这也需要对非负数起作用。例如,十六进制字符串"0000000A",它是二进制的0000000000000000000000000000000000001010和十进制的10。
对于同时使用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;
}
使用
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
,这就是在这种情况下没有溢出的原因。
好的,在转换之前,
strtol
正在考虑输入字符串,而不是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
。
我今天遇到了同样的问题,下面是我如何解决它的,这样我就可以保留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...
(当我正在寻找一种不那么糟糕的方式时,发现了这个页面:-)
干杯A。
Andy Buchanan,就坚持使用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");
这样,您就不需要为每个int类型执行一次impl。
这对我很有效:
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
下面是我在其他地方找到的一个简单有效的方法:
string hexString = "7FF";
int hexNumber;
sscanf(hexString.c_str(), "%x", &hexNumber);
请注意,您可能更喜欢使用无符号长整型/长整型来接收值。另请注意,c_str()函数只是将std::string转换为const char*。
因此,如果您已经准备好const char*,那么只需继续直接使用该变量名,如下所示,我还展示了无符号长变量对于较大十六进制数的用法。不要将其与使用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);
这可以很好地工作(如果您根据需要使用适当的数据类型)。
尝尝这个。这个解决方案有点冒险。没有支票。字符串必须仅具有十六进制值,并且字符串长度必须与返回类型大小匹配。但不需要额外的报头。
char hextob(char ch)
if (ch >= '0' && ch <= '9') return ch - '0';
if (ch >= 'A' && ch <= 'F') return ch - 'A' + 10;
if (ch >= 'a' && ch <= 'f') return ch - 'a' + 10;
return 0;
template<typename T>
T hextot(char* hex)
T value = 0;
for (size_t i = 0; i < sizeof(T)*2; ++i)
value |= hextob(hex[i]) << (8*sizeof(T)-4*(i+1));