如何防止用户堵塞扫描仪?

时间:2014-04-25 11:39:59

标签: java while-loop java.util.scanner

我正在写一个简单的投币游戏。前提很简单:用户可以调用头或尾。然后计算机翻转一枚硬币,通知用户投掷结果,以及他们是否猜对了。

就代码而言,在while循环中我首先提示用户输入,我使用我的Scanner的nextLine()读取,然后我将其分配给String变量。然后我调用feedback(),显示" Processing"到终端窗口并调用当前正在执行的Thread的sleep()。然后我检查他们的猜测,如果由于某种原因它无效,我向终端窗口显示一个适当的消息并将布尔值设置为true。这个布尔值的真实性是使while循环继续运行的原因。我不满意的是在while循环中,在我读到一个String并且正在执行feedback()之后,我仍然可以输入内容并按Enter键。然后,通过循环接下来的几次(在某些时候将提供的标志设置为true),它使用我为分配输入= reader.nextLine()输入的内容。我很惊讶。我认为当调用nextLine()时,扫描器只会读取一行输入,直到下一次调用nextLine()(即下一次循环)。但相反,当执行feedback()时,它似乎跟踪输入后输入的所有行= reader.nextLine()。以下是我的问题:有没有办法让扫描仪只能读取一行,并忽略用户输入的任何其他内容,直到下次您实际提示他们输入?换句话说,通过阻止用户输入阻塞扫描器并占用while循环多次传递的unledled-for输入,使游戏变得傻瓜?以下是我游戏的完整实现:​​

import java.util.Scanner;
import java.util.InputMismatchException;
import java.util.Random;

public class GuessingGame
{
    public static void main( String[] args ) throws InterruptedException
    {
        Random randy = new Random();
        Scanner reader = new Scanner( System.in );
        String input = "";
        int guess = 0; 
        boolean flag = true;

        System.out.println("Let's flip a coin!");

        while( flag )
        {
            flag = false;
            System.out.println("\fEnter 1 for heads, 2 for tails.");
            input = reader.nextLine();
            feedback("Processing");

            try
            {
                guess = Integer.parseInt( input );
            }
            catch( NumberFormatException e )
            {
                flag = true;
                System.out.println("Invalid!");
                Thread.sleep(3000);
            }

            if( !flag )
            {
                try
                {
                    receive( guess );
                }
                catch( IllegalArgumentException e )
                {
                    flag = true;
                    System.out.println( e );
                    Thread.sleep(3000);
                }
            }
        }

        feedback("Flipping");
        int outcome = randy.nextInt(2) + 1;

        if( outcome == 1 )
        {
            System.out.print("Heads! ");

            if( guess == 1 )
            {
                System.out.println("You guessed correctly.");
            }
            else
            {
                System.out.println("You guessed incorrectly.");
            }
        }
        else
        {
            System.out.print("Tails! ");

            if( guess == 2 )
            {
                System.out.println("You guessed correctly.");
            }
            else
            {
                System.out.println("You guessed incorrectly.");
            }
        }
    }

    public static void receive( int g )
    {
        if( g < 0 || g > 2 )
        {
            throw new IllegalArgumentException("Guess must be 1 or 2.");
        }
    }

    public static void feedback( String message ) throws InterruptedException
    {
        String feedback = message;
        System.out.println("\f");

        for( int x = 0; x < 12; x++ )
        {
            if( x % 4 == 0 )
            {
                feedback = message;
                Thread.sleep(250);
            }

            System.out.println("\f" + feedback );
            feedback += ".";
            Thread.sleep(125);
        }

        System.out.print("\f");
    }
}

2 个答案:

答案 0 :(得分:0)

最简单的方法就是在发布问题时阅读并丢弃扫描仪中的任何内容。扫描仪可能有一种方法可以清除它或寻找最终方法来做同样的事情。

答案 1 :(得分:0)

当您使用完扫描仪后,您应该致电reader.close()

在此处添加:

        try
        {
            guess = Integer.parseInt( input );
            reader.close();
        }

如果输入被正确解析,这将关闭扫描程序并阻止用户进一步交互。如果Integer.parseInt(input)抛出异常,则不会执行该行。

关闭扫描仪和其他读者/编写器是一种很好的做法,因为它会将内存释放回系统并防止出现类似程序的错误。