7

strtol我在 c 中遇到了一些不寻常的结果

这是示例程序。

#include <string.h>
#include <stdio.h>    
#include <stdlib.h>

int main()
{
    printf("%x\n", strtol("0xfffff70A", NULL, 0));
    return 0;
}

这个简单程序的输出是

0x7fffffff

而不是0xfffff70A. 如果我使用strtoul,结果是完全正确的0xfffff70a。我使用的是 32 位机器,我想知道会发生什么。PS。我正在使用 gcc 4.7.2

4

3 回答 3

7

来自 7.22.1.4 第 8 段(2011 版标准的 N1570 草案):

如果正确的值在可表示值的范围之外,LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX, ULONG_MAX, 或者ULLONG_MAX返回(根据返回类型和值的符号,如果有的话),宏的值ERANGE存储在errno中。

由于输入字符串的正确值对于该类型来说太大,因此您得到LONG_MAX,并且errno设置为ERANGE

每当其中一个strto(u)l(l)函数返回TYPE_MAXorTYPE_MIN值之一时,您需要检查errno它是否是正确的结果,或者您的输入是否超出范围。

于 2013-05-23T10:52:34.793 回答
1

您遇到了long签名类型的溢出。

您可能应该使用:

print("%lx\n", strtoul("0xfffff70a", NULL, 0));
                    ^
                    |
                 important!

相反,请注意“无符号”的“u”(参见手册页)。

另请注意,您不能打印unsigned longwith plain %x,您需要将其限定为大于int.

于 2013-05-23T10:53:13.890 回答
0

您的体系结构具有 32 位long类型。0xfffff70A不能表示为带符号的 32-bit longerrno应该设置为ERANGE.

在 2 的补码中,32 位有符号整数的可表示值范围从-0x800000000x7fffffff

于 2013-05-23T10:49:18.193 回答