Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C上的布尔表达式_C_Ascii - Fatal编程技术网

C上的布尔表达式

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

创建一个简单的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;
}
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.