在 Linux 32 位上带有 base 36 溢出无符号长长的 strtoull

strtoull with base 36 overflowing unsigned long long on Linux 32bit

本文关键字:溢出 无符号 长长的 strtoull base Linux      更新时间:2023-10-16

>有人知道为什么使用strtoull会压低无符号长长吗?当我拨打电话时,"x"的值是 12,所以我正在尝试将 12 位以 36 位为基数的 36 num 转换为无符号长整型。

这应该可以工作吗?我编译 32 位还是 64 位都没有关系。我在红帽上使用 g++。

缓冲区是字符*

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

谢谢!

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

我假设您的缓冲区没有以 nul 结尾;可能在您的 12 位以 36 为底的数字后面有一个字母数字字符。

顺便说一句,恕我直言,x最好算作endPtr - strPtr.投射到long并不是真的正确。

您似乎试图将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;