首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >检测strtol故障

检测strtol故障
EN

Stack Overflow用户
提问于 2014-09-28 01:37:41
回答 1查看 33.4K关注 0票数 25

如何检测strtol()是否没有转换一个数字?我在下面的简单案例中测试了它,并输出了0。现在最明显的问题是,我如何区分非转换和0的转换?

代码语言:javascript
运行
复制
long int li1;
li1 = strtol("some string with no numbers",NULL,10);
printf("li1: %ld\n",li1);

****
li1: 0
EN

回答 1

Stack Overflow用户

发布于 2014-09-28 09:31:30

strtol声明在stdio.h中如下:

代码语言:javascript
运行
复制
long int strtol(const char *nptr, char **endptr, int base);

strtol提供了一个健壮的错误检查和验证方案,允许您确定返回的值是valid还是invalid。基本上,您有三个主要工具可供您使用。(1)返回的值,(2)调用设置的值errno(3)提供和由strtol设置的nptrendptr的地址和内容。(有关完整的详细信息,请参阅man 3 strtol - man页面中的示例还提供了一组较短的条件供检查,但下面对它们进行了扩展以获得解释)。

在您的示例中,您将询问有关0返回值并确定其是否有效。正如您已经看到的,strtol返回的strtol值是而不是,意味着读取的数字是0,或者0是有效的。要确定0是否有效,还必须查看调用期间设置的errno值(如果已设置)。具体来说,如果errno != 0strtol返回的值是0,那么strtol返回的值是无效。(此条件将表示invalid baseunderflowoverflowerrno等于EINVALERANGE)。

第二个条件可能导致strtol返回一个无效的 0。在输入中没有读取位数的情况。当发生这种情况时,strtol会设置endptr == nptr的值。因此,在输入0值之前,还必须检查指针值是否相等。(可以使用字符串中的多个输入有效的 0 )

以下是评估strtol返回以及几种不同测试条件时要检查的不同错误条件的简短示例:

代码语言:javascript
运行
复制
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>

int main (int argc, char **argv)
{
    if (argc < 2) {
        fprintf (stderr, "\n Error: insufficient input. Usage: %s int [int (base)]\n\n", argv[0]);
        return 1;
    }

    const char *nptr = argv[1];                     /* string to read               */
    char *endptr = NULL;                            /* pointer to additional chars  */
    int base = (argc > 2) ? atoi (argv[2]) : 10;    /* numeric base (default 10)    */
    long number = 0;                                /* variable holding return      */

    /* reset errno to 0 before call */
    errno = 0;

    /* call to strtol assigning return to number */
    number = strtol (nptr, &endptr, base );

    /* output original string of characters considered */
    printf ("\n string : %s\n base   : %d\n endptr : %s\n\n", nptr, base, endptr);

    /* test return to number and errno values */
    if (nptr == endptr)
        printf (" number : %lu  invalid  (no digits found, 0 returned)\n", number);
    else if (errno == ERANGE && number == LONG_MIN)
        printf (" number : %lu  invalid  (underflow occurred)\n", number);
    else if (errno == ERANGE && number == LONG_MAX)
        printf (" number : %lu  invalid  (overflow occurred)\n", number);
    else if (errno == EINVAL)  /* not in all c99 implementations - gcc OK */
        printf (" number : %lu  invalid  (base contains unsupported value)\n", number);
    else if (errno != 0 && number == 0)
        printf (" number : %lu  invalid  (unspecified error occurred)\n", number);
    else if (errno == 0 && nptr && !*endptr)
        printf (" number : %lu    valid  (and represents all characters read)\n", number);
    else if (errno == 0 && nptr && *endptr != 0)
        printf (" number : %lu    valid  (but additional characters remain)\n", number);

    printf ("\n");

    return 0;
}

输出:

代码语言:javascript
运行
复制
$ ./bin/s2lv 578231

 string : 578231
 base   : 10
 endptr :

 number : 578231    valid  (and represents all characters read)

$ ./bin/s2lv 578231_w_additional_chars

 string : 578231_w_additional_chars
 base   : 10
 endptr : _w_additional_chars

 number : 578231    valid  (but additional characters remain)

$ ./bin/s2lv 578some2more3stuff1

 string : 578some2more3stuff1
 base   : 10
 endptr : some2more3stuff1

 number : 578    valid  (but additional characters remain)

$ ./bin/s2lv 00000000000000000

 string : 00000000000000000
 base   : 10
 endptr :

 number : 0    valid  (and represents all characters read)

$ ./bin/s2lv stuff578231

 string : stuff578231
 base   : 10
 endptr : stuff578231

 number : 0  invalid  (no digits found, 0 returned)

$ ./bin/s2lv 00000000000000000 -2

 string : 00000000000000000
 base   : -2
 endptr : (null)

 number : 0  invalid  (base contains unsupported value)
票数 63
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26080829

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档