第二个参数(char ** endptr)似乎是浪费空间!如果它设置为NULL,则STRTOL似乎沿着字符串向下运行,直到找到无效字符然后停止。如果字符串以无效字符开头,则函数返回ZERO(0),然后转换读取的所有有效字符。
这意味着以下代码应将2
检测为十六进制数:
int main()
{
char * string = "p1pp2ppp";
unsigned integer = strtoul(string, NULL, 16);
printf("%u", integer);
return 0;
}
但是,它返回零。
为什么?
手册页对第二个参数说了以下内容:
如果endptr不为NULL,则strtol()将第一个无效字符的地址存储在* endptr中。如果根本没有数字,strtol()将nptr的原始值存储在* endptr中(并返回0)。特别是,如果* nptr不是'\ 0'但返回时** endptr为'\ 0',则整个字符串有效。
例如:
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
我们可以看到当strtol
将p
指向str
中无法转换的第一个字符时。这可以用于一次解析一下字符串,或查看是否可以转换整个字符串或是否有一些额外的字符。
在您的示例中,string
中的第一个字符,即“p”不是基数10位,因此不会转换任何内容,函数返回0。
为什么?
它返回0
因为"p..."
不遵循任何关于整数表示的规则。第二个参数与您的问题无关。
所有char **endptr
函数中的strto*
参数旨在接收第一个字符的地址,该字符不是有效整数(十进制,十六进制或八进制)或浮点数的一部分。它不是无用的,它可以方便地检查无效输入。例如,如果我打算输入1234
但是像12w4
这样的胖子,strtoul
将返回12
并将endptr参数设置为指向w
。
基本上,如果字符endptr
指向的不是空格或0
,那么输入应该很可能被拒绝。