[英]How to validate input using scanf
如何使用scanf验证用户输入。 现在我有类似的东西,但不起作用。
注意:我有atoi只是为了验证scanf验证是否有效。
scanf("%[0987654321.-]s",buf);
i = atoi(buf);
if(i)
index = i;
使用scanf()
通常是用户输入的一个坏主意,因为失败会将FILE
指针留在未知位置。 这是因为scanf
代表“扫描格式化”,并且没有比用户输入更多的未格式化 。
我建议使用fgets()
来获取一行,然后在字符串上使用sscanf()
来实际检查和处理它。
这也允许您检查字符串中是否有您想要的字符(通过循环或正则表达式),这是scanf
系列函数不适合的。
举例来说,使用带有"%d"
或"%f"
scanf()
将停在第一个非数字字符处,因此不会捕获像"127hello"
这样的尾随错误, "127hello"
会给你127个。并且使用它与非约束%s
只是乞讨缓冲区溢出。
如果你真的必须使用[]
格式说明符(在scanf
或 sscanf
),我认为它的意思不是s
。
而且,对于使用该建议的强大输入解决方案,请参见此处 。 一旦你有一个输入行作为字符串,你可以sscanf
到你的心脏内容。
您似乎想要验证字符串作为输入。 这取决于您是否要验证字符串是否包含double或int。 以下检查double(允许前导和尾随空格)。
bool is_double(char const* s) {
int n;
double d;
return sscanf(s, "%lf %n", &d, &n) == 1 && !s[n];
}
sscanf
将返回转换的项目(没有'%n')。 n
将被设置为已处理输入字符的数量。 如果处理了所有输入,则s [n]将返回终止0字符。 两个格式说明符之间的空格占可选的尾部空格。
以下检查int,使用相同的技术:
bool is_int(char const* s) {
int n;
int i;
return sscanf(s, "%d %n", &i, &n) == 1 && !s[n];
}
有对一个问题在这里 ,其中也包括这样做更多的C ++“ISH的方式,比如使用字符串流和功能从提升,喜欢的lexical_cast等。 它们通常比scanf这样的函数更受欢迎,因为很容易忘记将一些'%'传递给scanf或某个地址。 scanf不会识别,但是会做任意事情,而lexical_cast例如,如果有什么不对的话会抛出异常。
我的方法是将用户输入读入字符串,然后使用strtol()
将其转换为long。 strtol()
返回指向它无法处理的输入字符串中第一个字符的指针,因此通过检查此字符,您将知道是否已解析完整字符串,如下所示:
char *string;
char *endptr;
long result;
scanf("%as", string);
errno = 0;
result = strtol(string, &endptr, 10);
if (ERANGE == errno)
printf("Input number doesn't fit into long\n");
else if (*endptr)
printf("%s is not a valid long number - it contains invalid char %c\n",
string, *endptr);
else
printf("Got %ld\n", result);
在这个片段中, scanf()
被指示使用格式修饰符“a”自动分配足够大的string
(这是GNU扩展)。 如果您不使用GNU,请手动分配string
并以scanf()
格式限制最大大小。
这种方法可以更好地处理错误。
您在scanf
的第一个参数中指定的是转换说明符 。 scanf
会尝试将输入转换为格式,但有时你可能会惊讶它会匹配:)
您应该做的第一个检查是来自scanf的返回值(它将为您提供匹配输入的数量)。 如果你没有得到你期望的数字,那么你就知道输入有问题了。 在你的情况下它应该是1。
if( scanf("%[0987654321.-]s", buf) == 1 )
{
if( sanit_check( buf ) )
{
/* good input */
}
else
{
/* invalid input */
}
}
else
{
/* invalid input */
}
除此之外,您需要对您要求scanf
执行的转换进行自己的完整性检查。
如果您只是想读取一个数字,请使用:
int i;
scanf( "%d", &i );
如果你需要做更复杂的检查,你必须自己做。 Scanf不会为你做这件事。
“buf”需要成为一个指针。 看起来你正在经历价值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.