创建一个简单的C函数,防止用户输入1到9之间的数字以外的任何数字。不应接受任何其他输入,包括字母符号和任何小于1且大于9的数字。 到目前为止它非常直接;但是,代码应该检查输入的字符不是符号或字母的部分不能按我希望的方式工作。
int validateUserInput(){
printf("%s\n", "Please enter a number from 1 to 9: ");
char value = getchar();
int numValue = value;
char temp;
int digitCounter = 0;
while((temp = getchar()) != '\n'){
digitCounter++;
}
//if there is more than 1 digit.
if(digitCounter>0){
printf("%s\n","Input too long!");
return validateUserInput();
}
// if the char entered is not between 1 and 9
// this part is giving me a hard time.
else if(numValue < 49 || numValue > 57){
printf("%s\n", "Imput is not within the valid parameters");
return validateUserInput();
}
return numValue;
}
答案 0 :(得分:1)
在输入输入例程时,还需要注意几点。如果用户需要取消输入怎么办? (例如,在Windows上按 ctrl + d 或 ctrl + z )正如您所写的那样,无法取消循环。 (虽然这仅用于强制1-9
的单个输入,但却无法取消)如果您捕获EOF
,则提供两者,取消方式和指示方式取消回调函数(例如,通过检查EOF
的回报)
虽然递归有它的位置,但要注意每个递归本身是一个单独的函数调用,需要一个单独的堆栈,以及函数调用的所有其他陷阱。很多时候,使用简单的goto
语句可以避免这种情况。 glibc经常使用goto
(例如,检查qsort
,getdelim
等来源。)在您的情况下,单个goto
标签可以完全消除需求用于递归。例如,您可以在满足所有条件的同时执行与以下类似的操作:
int validateuserinput()
{
int c, extra, tmp;
getinput:; /* a simple goto can avoid recursion completely */
extra = 0;
printf ("Please enter a number from 1 to 9: ");
/* prompt/loop while chars not between 1 and 9 */
for (c = getchar(); (c < '1' || '9' < c ); c = getchar()) {
if (c == '\n') { /* no digits in input */
fprintf (stderr, "error: invalid input.\n");
goto getinput;
}
else if (c == EOF) { /* trap EOF */
fprintf (stderr, "\nerror: input canceled.\n");
return c;
}
}
/* empty input buffer -- increment extra count */
for (tmp = getchar(); tmp != '\n' && tmp != EOF; tmp = getchar())
extra++;
if (extra) { /* if extra chars -- input too long */
fprintf (stderr, "error: input too long.\n");
goto getinput;
}
return c - '0'; /* return integer value instead of ASCII value */
}
(只是一个样式注释,C通常避免使用 camelCase 变量名来支持小写,这只是一般性,完全取决于你)
您可以使用以下短代码检查功能(并响应取消):
#include <stdio.h>
int validateuserinput();
int main (void) {
int n;
if ((n = validateuserinput()) != EOF)
printf ("\n valid input : %d\n", n);
return 0;
}
示例使用/输出
测试只接受1-9的输入:
$ ./bin/inputhandler
Please enter a number from 1 to 9: Hello World!
error: invalid input.
Please enter a number from 1 to 9: ?
error: invalid input.
Please enter a number from 1 to 9: 0
error: invalid input.
Please enter a number from 1 to 9: 23
error: input too long.
Please enter a number from 1 to 9: 6
valid input : 6
在Windows上测试输入取消(例如 ctrl + d 或 ctrl + z )
$ ./bin/inputhandler
Please enter a number from 1 to 9:
error: input canceled.
虽然使用递归没有任何问题,但总是有必要问“这是否需要以递归函数开始?”有时答案是肯定的,但通常很简单避免额外开销的方法。 (注意:一些递归的开销很小,所以在你的情况下它不是一个很重要的考虑因素,但如果你无意中调用一个旋转一百万次的递归函数,它很快就会成为一个问题)
查看所有答案,如果您有任何疑问,请告诉我们。
答案 1 :(得分:0)
您只需设置numValue
一次 - 对于第一个getchar()
- 看起来您希望在每getchar()
之后设置它。
答案 2 :(得分:-1)
while((temp = getchar()) != '\n'){
digitCounter++;
}
可能是
while((temp = getchar()) != '\n'){
if (temp < 49 || temp > 57 || ++digitCounter>0)
return validateUserInput();
}
这种方式让我觉得很简单