由于你的return_val是unsigned int,你可能应该使用自C89以来一直是标准的strtoul(),因此得到MSVC的支持(而strtoll()只是自C99以来的标准并且不受MSVC支持)。
您对错误条件的测试是不够的。在调用转换函数之前,需要将errno设置为零;您还需要检测是否报告了错误,这比看起来更棘手。
第§7.20.1.4节'C99标准的strtol,strtoll,strtoul和strtoull函数'表示:
返回
strtol,strtoll,strtoul和strtoull函数返回转换后的值(如果有的话)。如果无法执行转换,则返回零。如果正确的值超出可表示值的范围,则返回LONG_MIN,LONG_MAX,LLONG_MIN,LLONG_MAX,ULONG_MAX或ULLONG_MAX(根据值的返回类型和符号,如果有),并且宏ERANGE的值为存储在errno。
您还必须查看存储在endptr参数中的值到转换函数,以告知没有执行转换(与转换的有效零相反)。
如果主题序列为空或者没有预期的形式,则不进行转换; nptr的值存储在endptr指向的对象中,前提是endptr不是空指针。
所以,你必须编写更像这样的代码(省略对EINVAL的测试,因为标准没有提到将errno设置为EINVAL的这些函数):
unsigned int return_val=0;
if (index + 1 <= argc - 1)
{
char *end;
unsigned long ul;
errno = 0;
ul = strtoul(argv[index+1], &end, 10);
if ((ul == 0 && end == argv[index+1]) ||
(ul == ULONG_MAX && errno == ERANGE) ||
(ul > UINT_MAX))
{
fprintf(stderr, "Could not parse argument %s for switch %s!\n",
argv[index], argv[index+1]);
return 0;
}
retval = (unsigned int)ul;
}
请注意,这比有符号整数转换的测试更简单,必须考虑负_MIN限制以及_MAX限制。
另请注意,您确实应该将结果记录在unsigned long中,然后检查它是否适合您指定的范围,这可能仅限于UINT_MAX(在类似Unix的64位环境中可能小于ULONG_MAX)。