如何正确提示用户输入,直到他们提供有效的回复

时间:2017-12-02 17:19:19

标签: c io getchar

我想打印一个提示消息到标准输出,然后阅读 来自用户输入的标准输入的值(例如,数字)。

如果用户输入了无效值,我想再次打印提示,并且 再次阅读他们的回复,直到他们输入有效值(有点像 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

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

2 个答案:

答案 0 :(得分:1)

正如所说,如果输入包含值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;
}

答案 1 :(得分:0)

这可以使用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;
}