C上的布尔表达式
创建一个简单的C函数,防止用户输入除1到9之间的数字以外的任何内容。不接受任何其他输入,包括字母、符号和任何小于1且大于9的数字。 到目前为止,它相当直接;但是,代码应该检查输入字符是否不是符号或字母的部分没有按照我希望的方式工作C上的布尔表达式,c,ascii,C,Ascii,创建一个简单的C函数,防止用户输入除1到9之间的数字以外的任何内容。不接受任何其他输入,包括字母、符号和任何小于1且大于9的数字。 到目前为止,它相当直接;但是,代码应该检查输入字符是否不是符号或字母的部分没有按照我希望的方式工作 int validateUserInput(){ printf("%s\n", "Please enter a number from 1 to 9: "); char value = getchar(); int numValue = va
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;
}
int validateUserInput(){
printf(“%s\n”,“请输入1到9之间的数字:”);
char value=getchar();
int numValue=值;
焦炭温度;
int数字计数器=0;
而((temp=getchar())!='\n'){
数字计数器++;
}
//如果有超过1个数字。
如果(数字计数器>0){
printf(“%s\n”,“输入太长!”);
返回validateUserInput();
}
//如果输入的字符不在1和9之间
//这部分让我很难受。
否则如果(数值<49 | |数值>57){
printf(“%s\n”,“输入不在有效参数范围内”);
返回validateUserInput();
}
返回numValue;
}
您只设置了numValue
一次-对于第一次getchar()
-看起来您希望在每次getchar()
之后设置它
可能是
while((temp = getchar()) != '\n'){
if (temp < 49 || temp > 57 || ++digitCounter>0)
return validateUserInput();
}
while((temp=getchar())!='\n'){
如果(温度<49 | |温度>57 | |++数字计数器>0)
返回validateUserInput();
}
这样做很简单,我认为在使用输入例程进行输入时,还有几点需要注意。如果用户需要取消输入怎么办?(例如,在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 */
}
测试输入取消(例如,windows上的ctrl+d或ctrl+z)
虽然使用递归没有什么错,但询问“这是否需要一个递归函数开始?”总是有帮助的。有时答案是肯定的,但通常有一些简单的方法可以避免额外的开销。(注意:少量递归的开销是最小的,因此在您的情况下这不是一个大问题,但是如果您无意中调用了一个旋转一百万次的递归函数,它很快就会成为一个问题)
查看所有答案,如果您有任何问题,请告诉我们。不要使用49和57;使用
'1'
和'9'
。(这是“插补”或“输入”的拼写错误吗?)最好说“输入1到9之间的一位数”,清楚地表明范围。我甚至可以显示您拒绝的值。您希望函数返回ASCII码还是数字本身?如果是后者,则需要返回numValue-'0'
有isdigit(ch)
和
有strlen(str)
,您可以用它来解决您的问题。假设用户第一次键入567和换行符。此代码将读取循环外的5;它将读取循环中的6,并对函数进行递归调用,然后该函数将读取7和一个换行符,并对生活感到满意。不过,用户可能会对他们键入567时使用的数字为何为7感到困惑。我想最好使用(;)循环而不是getinput:
并将goto getinput
替换为continue
。是的,这是可能的,但我不确定它是否一定能改善任何效果。基本上将getchar()
移动到现有for
的上方,将for
转换为if
,将底部的extra
换行到else
中,并将所有内容换行到for(;)
在循环下方移动EOF
,同时在初始getchar()
之后还包括EOF
检查。如果您想先检查数字,您可以反转if
逻辑,但这种逻辑有点混乱。无论哪种方法都可以。for(;;)
表示无限循环,所以读者将从一开始就了解这一点。因此,它肯定会提高可读性。其他的改变是不需要的。我想我只需要看一个例子。您仍然需要处理上面的extra
循环,并在无限循环中出现多个数字时清空输入缓冲区。每次读取时,您都需要检查EOF
,或者在设置了错误条件的流上再次调用getchar
,冒未定义行为的风险。我在想什么?控制何时显示提示以及所需的错误消息完全是另一回事。
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 */
}
#include <stdio.h>
int validateuserinput();
int main (void) {
int n;
if ((n = validateuserinput()) != EOF)
printf ("\n valid input : %d\n", n);
return 0;
}
$ ./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
$ ./bin/inputhandler
Please enter a number from 1 to 9:
error: input canceled.