strtoull在Linux 32bit上使用base 36溢出unsigned long long

时间:2013-10-31 18:06:49

标签: c++ c linux integer

任何人都知道为什么使用strtoull会过度使用unsigned long long?当我拨打电话时,“x”的值是12,所以我试图将12位数的基数36转换为无符号长的。

这应该正常吗?无论我编译32位还是64位都没关系。我在redhat上使用g ++。

缓冲区是一个char *

char *strPtr = buffer + ORDERIDOFFSET;
char *endPtr = strPtr + ORDERIDLENGTH;
long x = long((endPtr)) - long(buffer + ORDERIDOFFSET);
unsigned long long orderid = strtoull((buffer + ORDERIDOFFSET), &(endPtr), 36);

谢谢!

2 个答案:

答案 0 :(得分:4)

您似乎误以为endptrstrtoull的输入参数,它告诉它输入字符串有多长。它不是。它是一个输出参数,strtoull用它来告诉你它无法转换的第一个字符。

我认为你的缓冲区不是nul终止的;可能在您的12位数字基数为36之后有一个字母数字字符。

顺便说一下,imho,x会更好地计算为endPtr - strPtr。转换为long并不正确。

答案 1 :(得分:1)

您似乎尝试使用endPtr作为输入参数。 std::strtoull将第二个参数作为输出参数。

您可能会发现使用std::stoull代替std::strtoull更加健壮:

char *strPtr = buffer + ORDERIDOFFSET;
char *endPtr = strPtr + ORDERIDLENGTH; // assuming ORDERIDLENGTH takes you 1 passed the end of the actual ID string
std::string s(strPtr, endPtr);
unsigned long long orderid = std::stoull(s, nullptr, 36);

此外,

long x = long((endPtr)) - long(buffer + ORDERIDOFFSET);

不能移植到64位系统(你会截断地址)。我很确定你想要

std::size_t x = endPtr - strPtr;