如何使用scanfvalidation输入
如何使用scanfvalidation用户输入。 现在我有这样的东西,但不起作用。
注意:我有atoi只是为了validationscanfvalidation是否有效。
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
到你的心脏内容。
您似乎想要validation字符串作为输入。 这取决于您是否要validation字符串是否包含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 ++的方法,比如使用字符串流和boost函数,比如lexical_cast等。 它们通常比scanf这样的函数更受欢迎,因为很容易忘记将一些’%’传递给scanf或某个地址。 scanf不会识别,但是会做任意的事情,而lexical_cast,例如,如果有什么不对的话会抛出exception。
我的方法是将用户输入读入字符串,然后使用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”(这是GNU扩展)自动分配足够大的string
。 如果您不使用GNU,请手动分配string
并以scanf()
格式限制最大大小。
这种方法允许更好的error handling。
您在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”需要成为一个指针。 看起来你正在经历价值。