简体   繁体   English

如何关闭循环内的扫描仪?

[英]How can I close a scanner that is inside of a loop?

This code works, but I'm left with a scanner that isn't closed, and when I try to close it, it results in a continuous loop. 这段代码有效,但是我剩下的扫描器没有关闭,当我尝试关闭它时,它会导致连续循环。 How can I close this scanner without it resulting in a continuous loop. 我如何关闭该扫描仪而不导致连续循环。

Here is my code: 这是我的代码:

    double startingAmount = 0;

    //Asks how much money customer has to spend, and will re-ask if an invalid input is put in.
    System.out.println("Please enter how much money you have to spend (enter -1 to shut down):");
     int x = 1;

     do {

     try {
         Scanner scanner = new Scanner(System.in);  
         startingAmount = scanner.nextDouble();
         x = 2;

     } catch (Exception e) {
         System.out.println(
                 "Invalid input, please enter how much money you have to spend (enter -1 to shut down):");             
     }

 } while (x == 1);  

Don't. 别。 Open it before the loop. 在循环之前将其打开。 Normally you would close it after the loop, but as it wraps System.in you should not close it at all. 通常,您将在循环后关闭它,但是当它包装System.in您根本不应该将其关闭。

Closing a IO Stream (which is what System.in is for the keyboard) is always a good idea so as to remove a potential resource leaks however in this particular case (being a console app) you should only Close a Scanner (using System.in) when you know you're completely finished with it. 关闭IO流(这是System.in在键盘上的作用)始终是一个好主意,以消除潜在的资源泄漏,但是在这种特定情况下(作为控制台应用程序),您仅应关闭扫描仪(使用系统)。 in),当您知道自己已经完全完成时。 In your case it will close automatically when your simple application ends. 在您的情况下,它将在您的简单应用程序结束时自动关闭。 Once you close Scanner which is using System.in , you will not be able to use System.in again during the current application session. 关闭使用System.in的 扫描仪后 ,将无法在当前应用程序会话期间再次使用System.in

Create your instance of scanner above the do/while loop. do / while循环上方创建扫描仪实例。 It's not a good idea to do it within the loop. 在循环中进行操作不是一个好主意。

As your code is currently written, only the Scanner.nextDouble() method requires the try/catch . 当前正在编写代码时,仅Scanner.nextDouble()方法需要try / catch Try to use proper Exceptions - It would be better to use InputMismatchException rather than just Exception . 尝试使用适当的Exceptions-最好使用InputMismatchException而不是Exception

Your initial prompt would be better placed within the beginning of you do/while loop removing the need for double prompting. 最好将您的初始提示放在do / while循环开始时, 无需重复提示。 Allow the catch block to merely indicate an Invalid Entry. 允许catch块仅指示无效条目。

Using do/while(true) or while(true){} may work better for you here rather than the use of the integer variable x and then in place of x = 2; 在这里,使用do / while(true)while(true){}可能比使用整数变量x然后代替x = 2;更好x = 2; use break; 使用break; . The way you're doing it with the int variable will work just fine and there is nothing wrong with it, as long as it will satisfy the condition for the loop and will at some point definitely exit that very same loop. 您使用int变量执行此操作的方式将正常工作,并且没有任何问题,只要它满足循环的条件并且在某个时候一定会退出相同的循环即可。 I just find it cleaner using while(true) and break; 我只是使用while(true)break来发现它更干净 for something as simple as this. 像这样简单的事情。 Of course this is just opinion based which we like to try and avoid. 当然,这只是基于意见,我们希望尝试避免。

You should place scanner.nextLine(); 您应该放置scanner.nextLine(); directly after the catch code block to clear the Scanner buffer since nextDouble() (or nextByte() , nextShort() , nextInt() , nextLong() , nextFloat() , etc) does not provide the newline character to do so. catch代码块之后直接清除扫描程序缓冲区,因为nextDouble() (或nextByte()nextShort()nextInt()nextLong()nextFloat()等)不提供换行符。 This will eliminate continuous looping on an Invalid Entry. 这将消除在无效条目上的连续循环。

StackOverflow has lots of examples of how to achieve what you are doing. StackOverflow提供了许多有关如何实现工作的示例。 You just need the yearning to search for them. 您只需要寻找它们。 Even placing something obscure like " how to prompt user in java console " into Google will produce around 4 million results. 即使将诸如“ 如何在Java控制台中提示用户 ”之类的晦涩的东西放到Google中,也会产生大约400万个结果。

Scanner implements the java.io.Closeable interface. Scanner实现java.io.Closeable接口。 Consequently you can instantiate new Scanner instances using the try-with-resources construct. 因此,您可以使用try-with-resources构造实例化新的Scanner实例。

If you really have to create your Scanner inside the do/while loop, you can do something similar to this: 如果确实需要在do/while循环内创建Scanner ,则可以执行以下操作:

public static void main(String[] args) {
    double startingAmount = 0;

    //Asks how much money customer has to spend, and will re-ask if an invalid input is put in.
    System.out.println("Please enter how much money you have to spend (enter -1 to shut down):");
    int x = 1;

    do {
        try (Scanner scanner = new Scanner(System.in)) {
            startingAmount = scanner.nextDouble();
            x = 2;
        }
    } while (x == 1);
}

However it might be a better idea to create the Scanner once using try-with-resources and add your loop inside the try block: 但是,最好使用try-with-resources创建一次扫描程序,然后在try块内添加循环,这是一个更好的主意:

public static void main(String[] args) {
    double startingAmount = 0;

    //Asks how much money customer has to spend, and will re-ask if an invalid input is put in.
    System.out.println("Please enter how much money you have to spend (enter -1 to shut down):");
    int x = 1;

    try (Scanner scanner = new Scanner(System.in)) {
        do {
            startingAmount = scanner.nextDouble();
            x = 2;
        } while (x == 1);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM