我有以下代码,要求用户输入 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 简介类(class)的作业要求,它对我有用。希望这也能澄清这个问题的愚蠢之处。
另请注意
timePeriod != 'A'
不起作用。我不知道为什么,但它不起作用。
最佳答案
建议将用户输入与验证分开。
scanf()
尝试同时执行这两项操作。如果仅读取一行输入(fgets()
- 标准或 getline()
common @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] == '\0') {
// 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);
关于c - 如何检查和验证用户输入是两个有效选择之一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31930841/