如何正确提示用户输入,直到他们给出有效响应

How to correctly prompt a user for input until they give a valid response

我想打印一条提示信息到标准输出,然后读取 用户输入的标准输入值(例如,数字)。

如果用户输入了无效值,我想再次打印提示,并且 再次阅读他们的回复,直到他们输入有效值(有点像 shells 工作)。

问题是当用户输入无效值时,提示莫名其妙 打印了两次,这不是我想要的。

这是我到目前为止尝试过的,但没有成功:

#include <stdio.h>

const char *prompt = "(Enter 1 to continue)> ";

int get_resp1(void)
{
    int r;
    fputs(prompt, stdout);
    r = getchar() - '0';
    if (r != 1)
        r = get_resp1();
    return r;
}

int get_resp2(void)
{
    int r;
    r = getchar() - '0';
    if (r != 1) {
        fputs(prompt, stdout);
        r = get_resp2();
    }
    return r;
}

int get_resp3(void)
{
    int r;
    fputs(prompt, stdout);
    do {
        r = getchar() - '0';
        if (r != 0)
            fputs(prompt, stdout);
    } while (r != 1);

    return r;
}

int main(void)
{
    int response;
    /* First attempt: */
    /* response = get_resp1(); */

    /* Second attempt */
    /* fputs(prompt, stdout); */
    /* response = get_resp2(); */

    /* Third attempt: */
    /* response = get_resp3(); */

    return response != 1;
}

这是我想要的结果:

(Enter 1 to continue)> 2
(Enter 1 to continue)>
(Enter 1 to continue)> 1

在第一行,我们输入非1的东西,在第二行 行,我们输入一个空行,最后,我们输入 1.

但这是我得到的结果(使用所有三种方法):

(Enter 1 to continue)> 2
(Enter 1 to continue)> (Enter 1 to continue)>
(Enter 1 to continue)> 1

注意提示在第二行打印了两次。

这可以使用 fgets 来实现:

int get_resp4(void)
{
    int r;
    char buf[0x7f];
    char *ptr = buf;
    fputs(prompt, stdout);
    fgets(buf, sizeof buf, stdin);

    while (*ptr && *ptr != '\n' && !isdigit(*ptr))
        ++ptr;
    if (!isdigit(*ptr))
        r = get_resp4();
    else
        r = *ptr - '0';

    if (r != 1)
        r = get_resp4();

    return r;
}

正如所说,如果输入包含值 1(具有零个或多个空格或制表符),那么它将被接受。任何其他字符组合都将被丢弃。

您可以更改代码以更改行为。这只是尝试使用问题中的 OP 预期的类似处理来演示 OP。

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdbool.h>

#define MAXBUFFSIZE 100
bool getConfirmation(){
    printf("\n%s",">> ");
    char buff[MAXBUFFSIZE];
    unsigned int success = 0;
    while( 1 ){
        success = 0;
        if( fgets(buff,MAXBUFFSIZE,stdin) == NULL){
            fprintf(stderr, "%s\n", "Error in input");
            break;
        }

        for( size_t i = 0;  i < strlen(buff); i++){
            if(isspace(buff[i]))
                continue;
            else if( isalpha(buff[i]))
                break;
            else if( isdigit(buff[i]) ){
                if( buff[i] == '1'){
                    success++;
                    if( success > 1)
                        break;
                }
                else{
                    success = 0;
                    break;
                }
            }
        }
        if( success == 1 )
            break;
        success =  0;
        printf("\n%s",">> ");
    }
    if( success == 0)
        return false;
    return true;
}
int main(){

    if( getConfirmation() == true )
        printf("%s\n","Continued ... ");
    else
        printf("%s\n","Error in input");
    return 0;
}