【问题标题】:Java Scanner next() reading range question [duplicate]Java Scanner next() 阅读范围问题[重复]
【发布时间】:2021-05-19 23:08:53
【问题描述】:

我有以下代码

public class ShoppingCartPrinter {
   public static void main(String[] args) {
      
      String productName;
      int productPrice = 0;
      int productQuantity = 0;
      int cartTotal = 0;
      
      String testStr = "Chocolate Chips\n3\n1\nChocolate Chips\n3\n1";
      
      Scanner scnr = new Scanner(testStr);

      productName = scnr.nextLine();
      System.out.println("1st Name " + productName);

      productPrice = scnr.nextInt();
      System.out.println("1st Price " + productPrice);

      productQuantity = scnr.nextInt();
      System.out.println("1st Quantity " + productQuantity);
      
      System.out.println();
      
      //scnr.nextLine();
      
      productName = scnr.nextLine();
      System.out.println("2nd Name " + productName);

      productPrice = scnr.nextInt();
      System.out.println("2nd Price " + productPrice);

      productQuantity = scnr.nextInt();
      System.out.println("2nd Quantity " + productQuantity);

   }
}

所以如果我不包括第 27 行,我会得到一个带有错误消息的输出:

1st Name Chocolate Chips
1st Price 3
1st Quantity 1

2nd Name 

Exception in thread "main" java.util.InputMismatchException
    at java.base/java.util.Scanner.throwFor(Scanner.java:939)
    at java.base/java.util.Scanner.next(Scanner.java:1594)
    at java.base/java.util.Scanner.nextInt(Scanner.java:2258)
    at java.base/java.util.Scanner.nextInt(Scanner.java:2212)
    at ShoppingCartPrinter.main(ShoppingCartPrinter.java:30)

我知道第 28 行的 scnr.nextLine() 读取不正确,因为之前的 scnr.nextInt() 没有使用 /n。但是,我不明白为什么第 31 行的 scnr.nextInt() 不会继续读取字符串中的下一个整数?

另外,如果 nextInt() 只能在一行内读取,或者它不能通过 /n,那么读取第一个数量的第二个 nextInt() 也应该给出错误,但它没有。

【问题讨论】:

  • 第 27 行是哪一行?
  • scnr.nextInt() 尝试读取的令牌是Chocolate Chips。因此,InputMismatchException.
  • 第 27 行是//scnr.nextLine();
  • 为什么scnr.nextInt() 不尝试阅读Chocolate Chips\n3\n1 而只是Chocolate Chips
  • 不,解释的问题nextInt() 没有读取/n,但没有说明为什么nextInt() 不会读取Chocolate Chips\n3\n1 而只有Chocolate Chips

标签: java input java.util.scanner newline next


【解决方案1】:
  System.out.println();
  productName = scnr.nextLine();

productName 在这里分配了System.lineSeparator 值,因为您刚刚打印了一个新行。当您认为您插入的是 productName 时,您实际上是在插入 nextInt() 将在此处读取的值:

 productPrice = scnr.nextInt(); //this will read the text you wanted for productName

【讨论】:

  • 但是scnr.nextInt() 为什么不忽略换行符后面的字符串,继续读取后面的整数呢?
  • nextInt() 正在读取一个字符串,即您对 productName 的输入。但是您的 productName 已经分配了行分隔符。所以你输入“apples”,扫描仪的调用是 nextInt()。
  • 感谢您如此耐心地回答我。为什么scnr.nextInt() 不是尝试阅读Chocolate Chips\n3\n1 而只是Chocolate Chips
  • 首先调用 nextLine(),它以 \n 结束。然后 nextInt() 读取 3。然后 nextInt 读取 1,因为它会跳过所有内容,直到找到 int
  • docs.oracle.com/javase/7/docs/api/java/util/… token 被转换为一个 int 值,就像通过删除所有区域设置特定前缀、组分隔符和区域设置特定后缀一样,
【解决方案2】:

您的代码有一点点错误
//scnr.nextLine(); 这一行对于在 Chocolate Chips 之前阅读 \n 很重要,如果您不使用虚拟 scnr.nextLine(); 阅读新的行,那么新行将在此处读取-

productName = scnr.nextLine();
      System.out.println("2nd Name " + productName);

这里productName 的值为\n,当它尝试读取时-

productPrice = scnr.nextInt();
      System.out.println("2nd Price " + productPrice);

它希望读取int,但发现String因此引发异常。

【讨论】:

  • 感谢您的回答,但我仍然不明白为什么scnr.nextLine(); 不会转义字符串“Chocolate Chips”并读取下一个整数?
  • 那是因为scnr.nextInt() 方法不会读取您输入中的换行符。换行符即\n也是一个字符串,写在巧克力片之前,当你第二个productName将读取\n作为它的输入,当productPrice尝试读取int时,它找不到并引发异常。
  • 方法是nextInt()nextLine(),所以它会读取下一个,而不是之前的。尝试将您的输入字符串更改为 Chocolate Chips\n3\n1\nChocolate Chips\n348\n1484 以查看它是否会一一解析字符串。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-29
  • 2020-02-01
  • 2010-11-30
  • 2023-03-27
  • 1970-01-01
相关资源
最近更新 更多