如何使用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”需要成为一个指针。 看起来你正在经历价值。