所以我有一个处理数字操作的任务,还包括错误检查。我遇到了错误检查方面的问题。用户通过命令行使用应用程序并提供8个空格分隔的数字。我在验证提供的数据实际上是整数时遇到了问题。
我被建议使用方法strtol()但是我知道如果整数无效,它返回0,但我需要返回错误消息而不是0,因为0有效。我可以使用另一种方法来验证输入吗?
答案 0 :(得分:3)
strtol
没有唯一的返回值来表示转换中的错误,它还有第二个参数(我的联机帮助页中的endptr
);如果你向它传递一个指向char *
的指针,它会在那里存储它无法转换的第一个字符的位置,或者如果没有任何东西可以转换就会保留它。因此,您有以下情况:
char * endptr=NULL;
int out=strtol(yourstring, &endptr, 10);
if(endptr==NULL)
{
/* the whole string is garbage - no numbers extracted */
}
else if(*endptr==0)
{
/* the whole string was a number - yay! */
}
else
{
/* strtol extracted a number from the string, but stopped at some invalid character
that you can check by looking at the value of endptr */
}
此外,您还可以检查strtol
设置errno
时遇到问题的值;如果无法提取任何内容,则会使用EINVAL
,其他值可以在strtol
的联机帮助页上看到。
您还可以使用sscanf
并检查其返回值,以快速查看字符串是否可以转换为int
(或者您在格式字符串中设置的任何内容)。
答案 1 :(得分:1)
如果strtol()
遇到错误,则会将errno
设置为EINVAL
。来自man page:
返回值
strtol()
函数返回转换结果,除非该值会下溢或溢出。 ...在这两种情况下,errno
都设置为ERANGE
。 ...错误
EINVAL
...给定的基数包含不受支持的值。 ...如果没有执行转换(没有看到数字,并且返回0),该实现也可以将
errno
设置为EINVAL
。< / p>
答案 2 :(得分:0)
命令行参数是字符串,为什么不使用isdigit(3)
?
答案 3 :(得分:0)
要正确使用strtol
,您必须在调用之前重置errno
。如果您编写要在其他项目中重用的代码,那么该代码应该没有意外的副作用。所以有两种变体:一种在您的情况下可能已经足够好的简单变体,以及在可重用代码库中可接受的复杂变体。
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
/* the simple variant, with the side-effect of changing errno */
static bool is_long_1(const char *s)
{
char *end;
errno = 0;
strtol(s, &end, 10);
return errno == 0 && *end == '\0';
}
/* the complex variant, without side-effects */
static bool is_long_2(const char *s)
{
char *end;
int saved_errno = errno;
errno = 0;
strtol(s, &end, 10);
bool succeeded = errno == 0 && *end == '\0';
errno = saved_errno;
return succeeded;
}
使用其中一个函数检查你的参数应该很容易,所以我把这一部分留给你找。