而 (!scannerObject.hasNext(patternObject)) 只适用于一次迭代

while (!scannerObject.hasNext(patternObject)) works for only one iteration

提问人:WarrenTheRabbit 提问时间:11/17/2020 最后编辑:WarrenTheRabbit 更新时间:11/17/2020 访问量:63

问:

问题

我只从由条件控制的循环中获得一次成功的迭代。我尝试“清除”输入流 (?),但没有成功。whilehasNext(Pattern pattern).next()

行为

如果我第一次输入无效的输入,看似有效的后续输入会继续执行该行。但是,只有当没有有效输入时,此行才应执行。System.out.print("You did not enter a valid size. Try again: ")Scanner getPizzaSize

相反,如果我第一次输入有效输入,它会起作用并且程序会前进,但是当进行第二次迭代时,所有输入(有效与否)都会执行行。while (orderingPizza)getPizzaSizeSystem.out.print("You did not enter a valid size. Try again: ")

我只从我的循环中得到一个成功的迭代:!getPizzaSize.hasNext(validPizzaSizes)

Please place the order for your pizza.
Size (s = small, l = large, f = family): s
Please place the order for your pizza.
Size (s = small, l = large, f = family): s
You did not enter a valid size. Try again: 

我应该得到:

Please place the order for your pizza.
Size (s = small, l = large, f = family): s
Please place the order for your pizza.
Size (s = small, l = large, f = family): s
Please place the order for your pizza.
Size (s = small, l = large, f = family):

(我使用的正则表达式应该匹配:s、S、l、L、f、F https://regexr.com/5gdla。

解决方案

如果我在循环中重新声明,循环的行为符合预期:Scanner getPizzaSize.hasNext(Pattern pattern)

  1. 无效输入后跟 ;和You did not enter valid input . . . try again
  2. 有效的输入通过程序前进

我想了解的内容

我如何从 .但我不知道问题出在哪里。这是我的正则表达式吗?关于与 ?对于整数输入,并且可以完美地工作。getPizzaSize.next().next().hasNext(Pattern pattern).hasNextInt().next()

import java.util.Scanner;
import java.util.regex.Pattern;

public class PizzaOrder{

    public static void main(String[] args) {
        // Initialise Scanner object.
        Scanner getPizzaSize = new Scanner(System.in);

        // Initialise Pattern object for detecting valid size input.
        Pattern validPizzaSizes = Pattern.compile("^[slf]$", Pattern.CASE_INSENSITIVE);

        while (true) {
            // Ask for pizza size.
            System.out.print("Please place the order for your pizza.\n" +
                    "Size (s = small, l = large, f = family): ");
            // Validate size input.
            while (!getPizzaSize.hasNext(validPizzaSizes)) {
                System.out.print("You did not enter a valid size. Try again: ");
                getPizzaSize.next();
            }
            // Set pizza size.
            String pizzaSize = getPizzaSize.next();
        }
    }
}
            
则表达式 java.util.scanner

评论


答:

1赞 Sweeper 11/17/2020 #1

您的正则表达式表示 “s”、“l” 或 “f” 必须是字符串的开头和结尾,如 和 锚点所示。但是,就扫描仪而言,您输入的秒数不在字符串的开头。这是在你第一次输入之后(可能也被线分隔符隔开)!^$ss

不应使用锚点。你的正则表达式应该是:^

[slf]$

这也解释了为什么创建新的扫描仪会起作用。因为新的扫描仪不知道您输入的上一个扫描仪。s

评论

0赞 WarrenTheRabbit 11/17/2020
我没有意识到以前的输入以某种方式仍然存在于字符串中。每次使用扫描仪时,我是否真的会在内存中构建越来越大的字符串?如果我收到足够的订单,我的内存会用完吗?
1赞 Sweeper 11/17/2020
@WarrenTheRabbit直到我在调试器中检查对象时,我才知道这一点!字符存储在一个名为 的数组中,所以我猜一旦它满了,它的内部逻辑就会清除它。ScannerbufScanner
0赞 WarrenTheRabbit 11/17/2020
不幸的是,我不知道在调试器中检查是什么意思!你是怎么做到的?我需要睡觉,但下次遇到问题时我想尝试在调试器中检查。如果你有一些建议,那就太好了。我会在早上阅读它们。如果没有,那就没问题了。感谢您付出的时间和帮助!Scanner
0赞 Sweeper 11/17/2020
@WarrenTheRabbit 只需查找如何在您正在使用的任何 IDE 中使用调试器即可。周围有很多教程。