strtoul() 函数中的第二个参数有什么作用?

What does the 2nd argument in strtoul() function do?

根据this document

The second argument (char **endptr) seems to be a waste of space! If it is set to NULL, STRTOL seems to work its way down the string until it finds an invalid character and then stops. All valid chars read are then converted if the string starts with an invalid character the function returns ZERO (0).

这意味着下面的代码应该将 2 检测为十六进制数:

int main()
{
    char * string = "p1pp2ppp";

    unsigned integer = strtoul(string, NULL, 16);

    printf("%u", integer);

    return 0;
}

但是,它返回零。

为什么?

Why?

它返回 0 因为 "p..." 不遵循任何关于整数表示的规则。 第二个参数与您的问题无关。

手册页对第二个参数的说明如下:

If endptr is not NULL, strtol() stores the address of the first invalid character in *endptr. If there were no digits at all, strtol() stores the original value of nptr in *endptr (and returns 0). In particular, if *nptr is not '[=16=]' but **endptr is '[=16=]' on return, the entire string is valid.

例如:

char str[] = "123xyz45";
char *p;
long x = strtol(str, &p, 10);
printf("x=%ld\n", x);
printf("p - str = %d\n", p - str);
printf("*p = %c\n", *p);
printf("p (as string) = %s\n", p);

输出:

x=123
p - str = 3
*p = x
p (as string) = xyz45

我们可以看到当strtolreturnsp指向str中第一个不能转换的字符。这可用于一次一点地解析字符串,或者查看是否可以转换整个字符串或是否有一些额外的字符。

在您的示例中,string 中的第一个字符,即 "p" 不是以 10 为基数的数字,因此不会进行任何转换,函数 returns 0.

所有 strto* 函数中的 char **endptr 参数旨在接收 不是 有效整数一部分的第一个字符的地址(十进制、十六进制或八进制)或浮点数。远非无用,它对检查无效输入很方便。例如,如果我打算输入 1234 但粗手指像 12w4strtoul 将 return 12 并将 endptr 参数设置为指向w

基本上,如果 endptr 指向的字符不是空格或 0,那么输入很可能会被拒绝。