繁体   English   中英

strtol的正确行为是什么?

[英]What is the correct behavior of strtol?

我正在为int16_t创建一个围绕strtol()的包装器函数,我遇到了一个问题:如何处理0x等输入? 也就是说,它是有效的数字0 ,后跟非数字x ,还是无效,因为0x没有任何内容?

tl; dr结果:Windows完全拒绝0x ,如后一种情况所述,但Debian将其视为数字0 ,后跟非数字字符x ,如前一种情况所述。

实施测试 1

  • 视窗
    • Visual C ++ 2015(以下简称MSVC)
    • MinGW-w64 GCC(5.2.0)
  • Debian的

为了进一步比较,我包含了格式规范为" %li" sscanf() ,它应该像strtol()使用base==0 令人惊讶的是,我最终得到了两个不同的结果。

码:

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

int main(void)
{
    const char *foo = "        0x";
    char *remainder;
    long n;
    int base = 0;

    n = strtol(foo, &remainder, base);
    printf("strtol(): ");
    if (*remainder == 'x')
        printf("OK\n");
    else {
        printf("NOMATCH\n");
        printf("  Remaining -- %s\n", remainder);
        printf("  errno: %s (%d)\n", strerror(errno), errno);
    }

    errno = 0;

    base = sscanf(foo, " %li", &n);
    printf("sscanf(): ");
    if (base == 1)
        printf("OK\n");
    else {
        printf("NOMATCH\n");
        printf("  Returned: %s\n", base==0 ? "0" : "EOF");
        printf("  errno: %s (%d)\n", strerror(errno), errno);
    }
}

Debian结果:

strtol(): OK
sscanf(): OK

Windows结果:

strtol(): NOMATCH
  Remaining --         0x
  errno: No error (0)
sscanf(): NOMATCH
  Returned: 0
  errno: No error (0)

在任何情况下都没有错误,但结果不同。 base初始化为16而不是0根本没有任何区别,也没有删除测试字符串中的前导空格。

老实说,我得到了Debian的结果: 0被解析为有效值(无论base是0还是16),并且在看到x后面没有有效的十六进制值时, remainder被设置为指向x (如果有的话)任何,无论base是0还是16,都会跳过0x )。

所以现在我对这种情况下的正确行为感到困惑。 这些行为中的任何一种都违反了C标准吗? 我对标准相关部分的解释是Debian是正确的,但我真的不确定。


1对于那些感兴趣的人,Cygwin在strtol()的情况下展示了Windows行为,在sscanf()的情况下展示了Debian行为。 由于行为是%li应该匹配strtol()base==0 ,我认为这是一个错误并忽略了它的结果。

C11的7.22.1.4中的规范:

  1. 如果base的值为零,则主题序列的预期形式是整数常量的形式,如6.4.4.1中所述,

  2. 主题序列被定义为输入字符串的最长初始子序列,从第一个非空白字符开始,即预期形式

如6.4.4.1中所述, 0是整数常量,但不是0x 因此,对于您的输入案例,主题序列为0

所以正确的行为是返回0 ,而endptr应该指向x

暂无
暂无

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

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