我在C中验证单字符scanf输入时遇到问题,我找不到现有的解决方案...
方案是:方法采用单字母'char'类型输入,然后验证此输入,如果不符合条件,则弹出错误消息并重新输入,否则返回此字符值。
我的代码是:
char GetStuff(void)
{
char c;
scanf("%c", &c);
while(c != 'A' || c != 'P')
{
printf("invalid input, enter again (A for AM or P for PM): ");
scanf ("%c", &dtChar);
}
return c;
}
然而,无论我输入什么输入,我都得到了无限循环的错误消息。我读了一些其他帖子并猜测%c说明符在我输入时没有自动摆脱换行的问题,到目前为止我有尝试:
scanf(" %c", &c);
GetStuff
方法中清理换行符,如:
void cleanBuffer(){
int n;
while((n = getchar()) != EOF && n != '\n' );
}
有谁能帮我解决这个问题吗?先感谢您。
#include <stdio.h>
char GetStuff(void) {
char c;
scanf("%c", &c);
getchar();
while ((c != 'A') && (c != 'a') && (c != 'P') && (c != 'p')) {
printf("invalid input, enter again (A for AM or P for PM): ");
scanf ("%c", &c);
getchar();
}
return c;
}
int main(void) {
printf("Calling GetStuff()...\n");
char x = GetStuff();
printf("User entered %c\n", x);
return 0;
}
您使用while (c != 'A' || c != 'P')
作为循环条件,但这将始终返回true。您打算使用的是&&“和”运算符,而不是|| “或”运营商。
另外,在scanf语句之后调用getchar()
来捕获换行符。这应该按照你想要的方式工作。
在内部循环中,你在dtChar
中输入,但你的循环条件检查变量c
,它在循环中没有更新,这导致无限循环
你也会改变你的状况
while(c != 'A' || c != 'P')
至
while(c != 'A' && c != 'P')
如果您希望用户输入“A”或“P”
请考虑以下代码段:
#include <stdio.h>
#include <ctype.h>
char GetStuff(void)
{
char c;
do {
printf("Please enter A for AM or P for PM: ");
scanf ("%c", &c);
// clean input buffer (till the end of line)
while(getchar()!='\n');
} while(toupper(c) != 'A' && toupper(c) != 'P');
return c;
}
int main(void)
{
printf("Your input is'%c'\n", GetStuff());
return 0;
}
注意要点:
while(c != 'A' || c != 'P')
将永远为真(因为一个字符不能同时是'A'和'P'),所以使用while(c != 'A' && c != 'P')
代替scanf
循环,不需要两个do..while
scanf
输入字符后,建议清除缓冲区中的所有字符,例如与while(getchar()!='\n');
(这将清除所有输入,包括不正确和冗余字符)toupper
避免进行4比较(实际上单个c=toupper(c)
内循环可以最小化你的时间为while(c != 'A' && c != 'P')
)更新:
添加消息“无效输入”并添加一些其他有用的改进...新代码如下:
#include <stdio.h>
#include <ctype.h>
void CleanBuffer(){
int n;
while((n = getchar()) != EOF && n != '\n' );
}
char GetStuff(void)
{
char c;
do {
printf("Please enter A for AM or P for PM: ");
scanf (" %c", &c);
c = toupper(c); // here letter become uppercase
CleanBuffer();
} while( (c != 'A' && c != 'P')?printf("Invalid input! "):0 );
return c;
}
int main(void)
{
printf("You have entered: %c\n", GetStuff());
return 0;
}
注意:函数将以大写形式返回“A”或“P”,因此如果不需要,请在更新之前更改代码(使用两个toupper
,并且不要在c
之后更改scanf
)。你也可以使用tolower
作为选项(当然与'a'
和'p'
比较)。
另一种可能的解决正如其他人提到的那样,条件是用&&完成的。无论如何,最大的问题是如何删除控制台输入线上剩下的内容。由于控制台按行工作,我们删除所有内容到下一个'\n'
。如果用户在调用GetStuff()
之前已经在输入行上留下了某些内容,那么在while循环之前添加对SkipRestOfTheLine()
的调用会很有用。
一般来说,我建议先使用while(1)
循环,然后再使其更好(例如在你发布的cleanBuffer()
中)。
#include <stdlib.h>
#include <stdio.h>
void SkipRestOfTheLine(void)
{
while (1) {
int c = fgetc(stdin);
if (c == EOF || c == '\n')
break;
}
}
char GetStuff(void)
{
while (1) {
int c = fgetc(stdin);
if (c == EOF)
exit(EXIT_FAILURE); // Deal with this case in an appropriate way
if (c == 'A' || c == 'P')
return c;
printf("invalid input, enter again (A for AM or P for PM): ");
SkipRestOfTheLine();
}
}
int main(void)
{
char c = GetStuff();
return 0;
}
试试这个,
char GetStuff(void)
{
char c;
scanf("%c", &c);
while (((c != 'A') || (c != 'a')) && ((c != 'P') || (c != 'p'))==1)
{
printf("invalid input, enter again (A for AM or P for PM): ");
scanf ("%c", &dtChar);
}
return c;
}
我希望这可行,有一段时间因为没有给出适当的支架,它会卡在循环中。