在C中,for循环中的scanf()导致printf()多次运行



我正在完成一项任务,完成后,我有一个错误,还有一个我不完全理解的错误修复。目前,只要用户按照要求去做,一切都很好。但我知道这种情况并不经常发生,所以我很想知道如何阻止这些问题。我喜欢任何建议-我是一个完全初学者与C.

我在这里找到了许多不同的建议:C:多重扫描';s、 当我输入一个扫描的值时,它会跳过的第二个扫描

我在scanf()语句中添加了一个空格,解决了一些错误,我知道它被添加到输入的字符串/字符的末尾,我只是不知道如何检查/处理它,我尝试使用getchar()代替scanf(。

错误问题

当用户在游戏循环中运行时,如果他们输入了1个以上的字符(例如:"oo",当用scanf()提示输入"y"或"n"时),我的printf语句会为每个输入的字符运行1x,并相互连接:

例如:

欢迎来到两扇门。

你想玩吗?(是/否):欢迎来到两扇门。

你想玩吗?(y/n):

如果用户输入"y"来玩游戏,但在第二部分中输入了1,2或3以外的字符,则也会出现此问题。

我如何限制他们回复的时间?或者,在输入if语句之前,监控游戏长度和选择变量的最佳方法是什么?也许检查一下它们是否超过1个字符,如果是,只取第一个字符?

第二个问题-我不理解的错误修复在scanf()函数中,我遇到了一个与上面描述的非常相似的问题,但当用户输入任何字符时都会出现这种情况。我找到的解决方案是在字符前面加一个空格->

scanf(" %c", &play);

scanf("%c", &play);

这个问题只是使用循环时的问题吗?因为在循环返回代码之前,我从未发现过这些错误。

已使用'while(getchar()!='更新代码\n');'Sourav Ghosh 的建议

#include <stdio.h>
int main(void) {
char play;
int choice;
char answer[] = "No matter which one you choose the guards both tell you which door leads to death, and therefore you can pick the other door.n";
int gameLoop = 1;
int timesPlayed = 0;
while (gameLoop == 1){
if (timesPlayed == 0) {
printf("Welcome to Two doors.n");
printf("Would you like to play? (y/n):");
} else {
printf("Would you like to play again? (y/n):");
}
scanf(" %c", &play);
while (getchar() != 'n');
if (play == 'y') {
// == instead of =
printf("nYou are a prisoner in a room with 2 doors and 2 guards.n");
printf("One of the doors will guide you to freedom and behind the other is a hangman --you don't know which is which.n");
printf("One of the guards always tells the truth and the other always lies. You don't know which one is the truth-teller or the liar either.n");
printf("You have to choose and open one of these doors, but you can only ask a single question to one of the guards.n");
printf("What do you ask so you can pick the door to freedom?nn");
printf("t1.Ask the truth-guard to point to the door of doom.n");
printf("t2.Ask the liar-guard to point to the door of doom.n");
printf("t3.Doesn't matter which one you pick.n");
scanf(" %d", &choice);
while (getchar() != 'n');
switch (choice) {
case 1:
printf("%s", answer);
timesPlayed++;
break;
case 2:
printf("%s", answer);
timesPlayed++;
break;
case 3:
printf("%s", answer);
timesPlayed++;
break;
default:
printf("The Troll Smasher comes out from the shadows and squeezes the stupid out of you until you pop. GAME OVER!n");
break;
}
} else if(play == 'n') {
printf("Sorry to hear that, we at Two Doors hope you have a super duper day!n");
gameLoop = 0;
break;
} else {
printf("That is not a valid input, please try again by entering either 'y' to start the game or 'n' to quit the game.n");
}
}
return 0;
}

%c格式说明符的问题是,它将只从输入缓冲区读取一个字节,如果输入缓冲区中存储了更多字节,并且下次遇到调用,它将不会请求用户输入,它只会从可用的输入流读取下一个字节。

所以,回答

如何限制他们的响应长度

好吧,没有直接的方法可以阻止用户只输入X字符/数字,相反,清除多余的字符/数字(如果有),对于下一次调用,从缓冲区开始是一种简单的方法。

因此,解决这一问题的快速方法是清除剩余输入的标准输入。你可以做一些类似的事情

int retval = scanf(" %c", &play);
//some code
while (getchar() != 'n');   //eat up the input buffer
//next call to scanf(), input buffer is empty now....

以阻止CCD_ 3读取已经存在的不需要的输入,并强制其向用户请求输入。

另外,不要忘记检查scanf()的返回值,以确保调用成功。

对于第一个问题,问题是因为程序的执行再次进入循环——例如,如果用户键入oo,这意味着在使用scanf读取后,它将一直进入最后一个循环。除此之外,没有任何变量被修改,因此当它重新进入循环时,gameRoop仍然是1,timesPlayed仍然是0,因此它将在第一个if中打印语句,然后scanf将读取第二个o并重复该过程。问题是scanf一次读取一个字符。

实际上,对于输入一个字符,您可以使用getchar(),但在任何情况下,在char输入之后,您都应该清除标准输入流。考虑以下示例,它强制用户进行正确的输入:

char name[11];
char answer = 0;
printf("Would you like to play again? (y/n): ");
while ((answer = getchar()) != 'y' && answer != 'n')
{
printf("You should answer 'y' or 'n'n");
// clean the buffer from mess
while (getchar() != 'n');
}
// clean the buffer from mess
while (getchar() != 'n');
// next input
printf("Enter your name: ");
scanf("%10s", name);
// clean the buffer from mess
while (getchar() != 'n');

更新:

只是为了澄清,代码

while ((answer = getchar()) != 'y' && answer != 'n')
{
printf("You should answer 'y' or 'n'n");
// clean the buffer from mess
while (getchar() != 'n');
}

在重写为时可以更容易理解

char name[11];
char answer = 0;
printf("Would you like to play again? (y/n): ");
while (1) // infinit loop 
{
answer = getchar();
// clean the buffer from mess (immideatly after reading) 
while (getchar() != 'n');
if (answer == 'y' || answer == 'n') // check the input
break; // stop the loop if condition is true
// or ask again
printf("You should answer 'y' or 'n'n");
}
// next input
printf("Enter your name: ");
scanf("%10s", name);
// clean the buffer from mess
while (getchar() != 'n');

在我的第一个例子中,我只是优化了代码,将读取和检查while之后括号中的数据结合起来:(answer = getchar()) != 'y'就像两个操作——answer = getchar()answer != 'y'

在最后一个代码段条件中,有意将answer != 'y' && answer != 'n'替换为answer == 'y' || answer == 'n',以显示"在数据不正确时执行"one_answers"在获得正确数据时停止"之间的区别

最新更新