我的猜谜游戏的一切都没问题,但当它询问用户是否想要再次玩时,它会重复两次问题。但是我发现如果我将输入方法从nextLine()更改为next(),它就不会重复这个问题。那是为什么?
这是输入和输出:
I'm guessing a number between 1-10
What is your guess? 5
You were wrong. It was 3
Do you want to play again? (Y/N) Do you want to play again? (Y/N) n
这是代码:(用Java编写) 最后一个while循环块是它询问用户是否想要再次播放的部分。
import java.util.Scanner;
public class GuessingGame
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
boolean keepPlaying = true;
System.out.println("Welcome to the Guessing Game!");
while (keepPlaying) {
boolean validInput = true;
int guess, number;
String answer;
number = (int) (Math.random() * 10) + 1;
System.out.println("I'm guessing a number between 1-10");
System.out.print("What is your guess? ");
do {
validInput = true;
guess = input.nextInt();
if (guess < 1 || guess > 10) {
validInput = false;
System.out.print("That is not a valid input, " +
"guess again: ");
}
} while(!validInput);
if (guess == number)
System.out.println("You guessed correct!");
if (guess != number)
System.out.println("You were wrong. It was " + number);
do {
validInput = true;
System.out.print("Do you want to play again? (Y/N) ");
answer = input.nextLine();
if (answer.equalsIgnoreCase("y"))
keepPlaying = true;
else if (answer.equalsIgnoreCase("n"))
keepPlaying = false;
else
validInput = false;
} while (!validInput);
}
}
}
答案 0 :(得分:7)
在do while
循环中,您不需要nextLine()
,只需要next()
。
所以改变这个:
answer = input.nextLine();
到此:
answer = input.next();
注意,正如其他人所建议的那样,您可以将其转换为while
循环。原因是当您需要至少执行一次循环时使用do while
循环,但您不知道执行它的频率。虽然在这种情况下它确实可行,但这样的事情就足够了:
System.out.println("Do you want to play again? (Y/N) ");
answer = input.next();
while (!answer.equalsIgnoreCase("y") && !answer.equalsIgnoreCase("n")) {
System.out.println("That is not valid input. Please enter again");
answer = input.next();
}
if (answer.equalsIgnoreCase("n"))
keepPlaying = false;
只要未输入“y”或“n”(忽略大小写),while
循环就会保持循环。一旦它,循环结束。如果需要,if
条件会更改keepPlaying值,否则不会发生任何事情,并且您的外部while
循环再次执行(从而重新启动程序)。
编辑:这解释了原始代码无效的原因
我应该补充一下,原始陈述不起作用的原因是因为你的第一个do while
循环。在其中,您使用:
guess = input.nextInt();
这会读取该行的数字,但不会返回该行的数字,这意味着您使用:
answer = input.nextLine();
它会立即从nextInt()
语句中检测到剩余的运输。如果您不想使用我的next()
阅读解决方案,您可以通过这样做来吞下这个剩余的:
guess = input.nextInt();
input.nextLine();
rest of code as normal...
答案 1 :(得分:5)
问题实际上在于完全不同的代码段。在前一个循环guess = input.nextInt();
中执行时,它会在输入中留下换行符。然后,当在第二个循环中执行answer = input.nextLine();
时,已经有一个等待读取的换行符,它返回一个空字符串,激活最终的else
并执行validInput = false;
,重复循环(和问题)。
一种解决方案是在第二个循环之前添加input.nextLine();
。另一种方法是使用guess
读取nextLine()
,然后将其解析为int。但是这会使输入变得复杂int
。再想一想,代码已经提出了这个问题。尝试输入非数字回复。所以,定义一个函数
public static int safeParseInt(String str) {
int result;
try {
result= Integer.parseInt(str) ;
} catch(NumberFormatException ex) {
result= -1 ;
}
return result ;
}
然后用:
替换你的第一个循环do {
validInput= true ;
int guess= safeParseInt( input.nextLine() ) ;
if( guess < 1 || guess > 10 ) {
validInput= false ;
System.out.print("That is not a valid input, guess again: ");
}
} while( !validInput );
PS:我认为do-while
循环没有任何问题。它们是语言的一部分,语法清楚地表明在主体执行至少一次之后评估条件。我们不需要删除语言的有用部分(至少从实践中删除)只是因为其他人无法了解它们。相反:如果我们确实使用它们,它们会更好地被人知道!
答案 2 :(得分:4)
validInput = false;
do {
System.out.print("Do you want to play again? (Y/N) ");
answer = input.next();
if(answer.equalsIgnoreCase("y")){
keepPlaying = true;
validInput = true;
} else if(answer.equalsIgnoreCase("n")) {
keepPlaying = false;
validInput = true;
}
} while(!validInput);
我改变了编码风格,因为我发现这种方式更具可读性。
答案 3 :(得分:2)
你的问题是nextInt
会在int结束后立即停止,但会将换行符留在输入缓冲区中。为了使你的代码能够正确地阅读答案,你必须在猜测的同一行输入它,比如 5 Space Y < KBD>返回
要使其行为超出预期,如果它只包含空格,则忽略第一个nextLine
结果,在这种情况下只需再次调用nextLine
而不打印消息。
答案 4 :(得分:1)
我相信input.nextLine()
的输出将包含行尾的换行符,而input.next()
则不会(但Scanner
将保持在同一行)。这意味着输出永远不会等于"y"
或"n"
。请尝试trimming结果:
answer = input.nextLine().trim();