简体   繁体   English

strtol()返回不正确的值

[英]strtol() returns an incorrect value

I've got a weird one here. 我在这里有一个奇怪的。 strtol, atol and atoi all return an incorrect value when I pass in the following string: 当我传入以下字符串时,strtol,atol和atoi都返回不正确的值:

long test = strtol("3087663490", &p, 10);

According to my debugger it returns 2147483647. I'm completely stumped on this. 根据我的调试器它返回2147483647.我完全被这个难倒了。 Any advice? 有什么建议?

Your value is larger than what a signed long type can represent. 您的值大于签名的long类型可以表示的值。 Try: 尝试:

unsigned long test = strtoul("3087663490", &p, 10);

(You're getting 2147483647 since it is LONG_MAX or 0x7FFFFFFF) (你得到的是2147483647,因为它是LONG_MAX或0x7FFFFFFF)

Correctly testing for errors from strtol() is tricky. 正确测试strtol()错误很棘手。 You need code similar to the below: 您需要类似下面的代码:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>

int main()
{
    char *n = "3087663490";
    char *p;
    long test;

    errno = 0;
    test = strtol(n, &p, 10);

    if (p == n)
        printf("No digits found.\n");
    else if ((test == LONG_MIN || test == LONG_MAX) && errno == ERANGE)
        printf("Value out of range.\n");
    else
        printf("Value is %ld\n", test);

    return 0;
}

Running this shows what your problem is - Value out of range. 运行它会显示您的问题 - Value out of range. . Use a wider type, like long long (and strtoll() ). 使用更宽的类型,如long long (和strtoll() )。

It appears long is a 32-bit type on your system. 它看起来long是您系统上的32位类型。 If that's the case, 3087663490 is larger than LONG_MAX . 如果是这种情况, 3087663490大于LONG_MAX From the strtol(3) man page : strtol(3)手册页

If an overflow occurs, strtol() returns LONG_MAX . 如果发生溢出, strtol()将返回LONG_MAX

You need to use an unsigned type to represent that number on your machine: 您需要使用无符号类型来表示计算机上的该数字:

unsigned long test = strtoul("3087663490", &p, 10);

Should work fine. 应该工作正常。

After returning from strtol check the value of p . 从strtol返回后检查p的值。 I believe that if you went over the size limit the return value will be LONG_MAX and the pointer will still be pointer at a digit rather than whitespace or text. 我相信如果你超过了大小限制,返回值将是LONG_MAX 指针仍然是指针数字而不是空格或文本。

And I also see after checking that errno will be set to ERANGE . 并且在检查之后我也会看到errno将被设置为ERANGE

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM