如何检查和验证用户输入是两个有效选择之一

How to check and validate user input is one of two valid choices

我有以下代码要求用户输入 A 或 P。我对小时和分钟有相同类型的设置,其中小时在 1 到 12 之间,分钟在 0 到 59 之间。那部分我的代码完全有效。

我的问题是我不知道如何检查 timePeriod 变量是什么并确保它是 A 或 P 并打印一条错误消息并再次提示它是否是其他任何东西,包括小写 a 和 p .用户输入必须是大写字母,并且只能是 A 或 P。

我这里只放了功能代码。我还添加了 clean_stdin 代码,因此 getTimePeriod 中的 while 语句可能更容易理解。正如我之前所说,我在小时和分钟上都使用了类似的设置,这很有效。

char getTimePeriod(void)
{
    char timePeriod, term;

    while ( (((scanf("%c%c",&timePeriod,&term)!=2 || term !='\n') && clean_stdin()) || timePeriod != "A" || timePeriod != "P") && printf("Invalid value entered. Must be A or P. Please re-enter: ") );

    return timePeriod;
}


int clean_stdin()
{
    while (getchar()!='\n');
    return 1; 
}

编辑: 对于那些因为这是糟糕的代码而感到内裤扭曲的人,根据我对 C 简介的作业要求,它对我有用当然。希望这也能澄清这个问题的新手性。

另请注意

timePeriod != 'A'

不起作用。我不知道为什么,但它不起作用。

建议将用户输入与验证分开。

scanf() 尝试同时执行这两项操作。如果仅读取一行输入(fgets() - 标准或 getline() 常见 @Jonathan Leffler)然后通过各种方式解析,则处理潜在的错误用户输入会更容易。

// return choice or EOF
int GetChoice(const char *prompt, const char *reprompt, const char *choices) {
  char buf[10];
  puts(prompt);
  while (fgets(buf, sizeof buf, stdin)) {
    buf[strcspn(buf, "\n")] = 0;  // drop potential trailing \n
    char *p = strchr(choices, buf[0]);
    if (p && buf[1] == '[=10=]') {
      // Could fold upper/lower case here if desired.
      return *p;
    }
    puts(reprompt);
  }
  return EOF;
}

int timePeriod = GetChoice("TimePeriod A or P", "Try Again", "AP");
switch (timePeriod) {
  case 'A' : ...
  case 'P' : ...
  default: ...

可以添加额外的检查。这是将其转为辅助函数的最佳部分,它可以在代码中的多个位置使用,并根据需要以本地化方式进行改进。


OP代码注释:
用户输入不符合预期,不清楚 OP 的复杂 while() 条件是否会正确清空用户的输入行。如果遇到 EOF 或者第一个 char'\n'.

肯定有问题

timePeriod != "A" @Alan Au 所评论的不是所需的代码。将 timePeriod 与字符串 "A" 的地址进行比较。使用 timePeriod != 'A'.

clean_stdin() 应该是 clean_stdin(void)。它是 EOF 上的无限循环。考虑:

int ch;
while ((ch = getchar()) != '\n' && ch != EOF);

您遇到的问题在这里:

timePeriod != "A" || timePeriod != "P"

首先,如前所述,您不能将字符与字符串进行比较。您需要使用单引号而不是双引号。假设已更正,此条件将始终为真,因为 timePeriod 将始终不是 'A' 或不是 'P'。这需要是逻辑与:

(timePeriod != 'A' && timePeriod != 'P')

另请注意,添加了一组额外的括号以确保保留 while 表达式中的运算顺序。

关于 "cute" 注释,这意味着在 while 表达式中塞进一堆语句并将正文留空会使您的代码难以阅读,因此更容易出现错误。如果你把它分解成多个语句,每个语句都做一件合乎逻辑的事情,你就更有可能自己发现这个错误。 Olaf 发表评论主要是为了警告其他看到您的代码的用户。