根据strtoul
的文档,关于其返回值...
此函数将转换后的整数返回为long int值。如果无法执行有效的转换,则返回零值。
如果我要解析用户提供的字符串“ 0”,对于我的应用程序来说,“ 0”可能是有效条目,该怎么办?在那种情况下,似乎无法通过使用strtoul
来确定是否执行了有效的转换。还有另一种方法可以解决这个问题吗?
答案 0 :(得分:6)
进一步阅读man page:
由于
strtoul()
可以成功返回0
或ULONG_MAX
({{1}的ULLONG_MAX
),因此调用程序应将{{1 }}到调用前的strtoull()
,然后通过检查调用后errno
是否具有非零值来确定是否发生了错误。
此外,要处理另一种情况,即在输入中未读取任何数字。如果发生这种情况,0
会将errno
的值设置为strtol()
的值。因此,您还应该检查指针值是否相等。
答案 1 :(得分:3)
如何使用
strtoul
解析可能为零的字符串?
从strtoul()
返回的任何值都可能来自预期的字符串输入,或者来自 other 的非预期字符串。进一步的测试很有用。
以下所有字符串从strtoul()
"0"
,"-0"
,"+0"
""
,"abc"
" 0"
"0xyz"
,"0 "
,"0.0"
strtoul()
具有多种检测模式。
int base = 10;
char *endptr; // Store the location where conversion stopped
errno = 0;
unsigned long y = strtoul(s, &endptr, base);
if (s == endptr) puts("No conversion"); // "", "abc"
else if (errno == ERANGE) puts("Overflow");
else if (*endptr) puts("Extra text after the number"); // "0xyz", "0 ", "0.0"
else puts("Mostly successful");
尚未检测到的内容。
负输入。 strtoul()
有效地环绕了strtoul("-1", 0, 10) == ULONG_MAX)
。 通常在粗略的文档审阅中都会遗漏此问题。
允许前导空白。
还要检测负值:
// find sign
while (isspace((unsigned char) *s)) {
s++;
}
char sign = *s;
int base = 10;
char *endptr; // Store the location where conversion stopped
errno = 0;
unsigned long y = strtoul(s, &endptr, base);
if (s == endptr) puts("No conversiosn");
else if (errno == ERANGE) puts("Overflow");
else if (*endptr) puts("Extra text after the number");
else if (sign == '-' && y != 0) puts("Negative value");
else puts("Successful");
答案 2 :(得分:1)
考虑以下功能:
#include <stdlib.h>
#include <errno.h>
/* SPDX-Identifier: CC0-1.0 */
const char *parse_ulong(const char *src, unsigned long *to)
{
const char *end;
unsigned long val;
if (!src) {
errno = EINVAL;
return NULL;
}
end = src;
errno = 0;
val = strtoul(src, (char **)(&end), 0);
if (errno)
return NULL;
if (end == src) {
errno = EINVAL;
return NULL;
}
if (to)
*to = val;
return end;
}
此函数解析字符串src
中的无符号long,返回指向src
中第一个未解析字符的指针,并将无符号long保存到*to
。如果有错误,该函数将返回NULL,并设置errno来指示错误。
如果将函数与man 3 strtoul
进行比较,您会看到它可以正确处理所有错误情况,并且仅在src
产生有效的无符号长整数时返回非NULL。特别是请参阅“注释”部分。还请注意负数的处理方式。
此模式适用于strtol()
,strtod()
,strtoull()
。
答案 3 :(得分:0)
一种解决方案是传递char
指针的地址,并检查其是否指向字符串的开头:
char *str = "0";
char *endptr;
unsgined long x = strtoul(str, &endptr, 10);
if(endptr == str)
{
//Nothing was read
}