0

I have the following code

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);

   }
}

So if I don't include line 27, I got an output with error message:

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)

I understand the scnr.nextLine() at line 28 didn't read correctly because the previous scnr.nextInt() didn't consume the /n. But, I don't understand why the scnr.nextInt() at line 31 won't just continue to read the next integer in the string?

Also, if the nextInt() can only read within one line, or it can't pass the /n, then the second nextInt() to read the 1st quantity should also give an error, however it didn't.

sxy
  • 21
  • 3
  • Which is line 27? – user207421 Feb 17 '21 at 04:24
  • The token which your `scnr.nextInt()` is trying to ***read*** is `Chocolate Chips`. Hence, the `InputMismatchException`. – AKSingh Feb 17 '21 at 04:29
  • Line 27 is ```//scnr.nextLine();``` – sxy Feb 17 '21 at 04:37
  • why the ```scnr.nextInt()``` is not try to read ```Chocolate Chips\n3\n1``` but only ```Chocolate Chips``` ? – sxy Feb 17 '21 at 04:37
  • No, the question explaned ```nextInt()``` doesn't read the ```/n```, but it didn't say why ```nextInt()``` won't read ```Chocolate Chips\n3\n1``` but only ```Chocolate Chips``` – sxy Feb 17 '21 at 04:39

2 Answers2

2
  System.out.println();
  productName = scnr.nextLine();

The productName is assigned System.lineSeparator value here, because you just printed a new line. When you believe you're inserting the productName, you really are inserting the value that nextInt() will read here:

 productPrice = scnr.nextInt(); //this will read the text you wanted for productName
aran
  • 9,202
  • 4
  • 30
  • 62
  • But why wouldn't the ```scnr.nextInt() ``` ignores the string after the newline, and continue to read the integer after it? – sxy Feb 17 '21 at 04:34
  • nextInt() is reading an String, your input for productName. But your productName was already assigned the line separator. So you enter "apples" and the scanner's call is nextInt(). – aran Feb 17 '21 at 04:36
  • Thank you for answering me so patiently. Why the ```scnr.nextInt()``` is not try to read ```Chocolate Chips\n3\n1``` but only ```Chocolate Chips``` ? – sxy Feb 17 '21 at 04:40
  • First you call nextLine(), which ends at `\n`. Then the nextInt() reads 3. Then nextInt reads 1, because it skips everything until an int is found – aran Feb 17 '21 at 04:42
  • https://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#nextInt() *the token is converted into an int value as if by removing all locale specific prefixes, group separators, and locale specific suffixes,* – aran Feb 17 '21 at 04:43
  • In order to solve it, it's easy: delete the println() before the 2nd product name – aran Feb 17 '21 at 04:44
  • println is output, which has absolutely nothing to do with your input stream – Patrick Parker Feb 17 '21 at 05:55
1

There is a little fault in your code
//scnr.nextLine(); this line is important to read \n before Chocolate Chips, If you wont use a dummy scnr.nextLine(); to read the new line then the new line will be read over here-

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

Here the productName will have the value \n and when it tries to read-

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

It expects to read an int but finds an String hence throws an exception.

Vyom Yadav
  • 1
  • 12
  • Thank you for answing, but I still don't understand why the ```scnr.nextLine();``` will not scape the string "Chocolate Chips" and read the next integer? – sxy Feb 17 '21 at 04:36
  • That's because the `scnr.nextInt()` method does not read the newline character in your input. The newline character i.e. `\n` is also a String and is written before Chocolate Chips, when you come on the 2nd one `productName` will read `\n` as its input and when `productPrice` tries to read an `int`, it can't find one and throws an exception. – Vyom Yadav Feb 17 '21 at 04:41
  • The method is `nextInt()` or `nextLine()`, so it will read the next one, not the ones before. Try changing your input String to `Chocolate Chips\n3\n1\nChocolate Chips\n348\n1484` to see that is parses the string one by one. – Vyom Yadav Feb 17 '21 at 04:46