Java .nextLine()重复行

时间:2013-08-19 18:38:37

标签: java

我的猜谜游戏的一切都没问题,但当它询问用户是否想要再次玩时,它会重复两次问题。但是我发现如果我将输入方法从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);
        }
    }
}

5 个答案:

答案 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();