5

Everything of my guessing game is alright, but when it gets to the part of asking the user if he/she wants to play again, it repeats the question twice. However I found out that if I change the input method from nextLine() to next(), it doesn't repeat the question. Why is that?

Here is the input and output:

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

Here is the code:(It is in Java) The last do while loop block is the part where it asks the user if he/she wants to play again.

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);
        }
    }
}
4

5 回答 5

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;

while只要没有输入“y”或“n”(忽略大小写),循环就会一直循环。一旦它是,循环结束。如果需要,if条件会更改 keepPlaying 值,否则不会发生任何事情,并且您的外部while循环会再次执行(从而重新启动程序)。

编辑:这解释了为什么您的原始代码不起作用

我应该补充一下,您原来的陈述不起作用的原因是因为您的第一个do while循环。在其中,您使用:

guess = input.nextInt();

这会读取线下的数字,但不会读取线的返回值,这意味着当您使用时:

answer = input.nextLine();

nextInt()它立即从语句中检测到剩余的托架。如果你不想使用我的阅读解决方案,next()你可以这样做吞下剩下的:

guess = input.nextInt();
input.nextLine();
rest of code as normal...
于 2013-08-19T18:47:29.813 回答
5

问题确实在于完全不同的代码段。在guess = input.nextInt();执行前一个循环时,它会在输入中留下一个换行符。然后,当answer = input.nextLine();在第二个循环中执行时,已经有一个换行符等待读取并返回一个空字符串,该字符串激活最终else并被validInput = false;执行,以重复循环(和问题)。

input.nextLine();一种解决方案是在第二个循环之前添加一个。另一种是读取guessnextLine()然后将其解析为 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 );

do-whilePS:我认为循环没有任何问题。它们是语言的一部分,语法清楚地表明条件在主体至少执行一次后进行评估。我们不需要仅仅因为其他人不知道而删除语言中有用的部分(至少从实践中)。相反:如果我们确实使用它们,它们会变得更广为人知!

于 2013-08-19T19:12:19.697 回答
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);

我改变了编码风格,因为我发现这种方式更具可读性。

于 2013-08-19T18:43:40.287 回答
2

您的问题是,nextInt一旦 int 结束,它将停止,但将换行符留在输入缓冲区中。为了让您的代码正确读取答案,您必须在猜测的同一行输入它,例如5SpaceYReturn.

为了使其行为超出预期,如果第一个nextLine结果仅包含空格,则忽略它,并nextLine在这种情况下再次调用而不打印消息。

于 2013-08-19T19:06:33.413 回答
1

我相信 的输出input.nextLine()将包括行尾的换行符,而input.next()不会(但Scanner将保持在同一行)。这意味着输出永远不等于"y"or "n"。尝试修剪结果:

answer = input.nextLine().trim();
于 2013-08-19T18:45:08.910 回答