• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Liutauras Vilda
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Ron McLeod
  • Devaka Cooray
  • Henry Wong
Saloon Keepers:
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Tim Moores
  • Mikalai Zaikin
Bartenders:
  • Frits Walraven

How to use a Scanner to get two sets of data from stdin?

 
Ranch Hand
Posts: 662
3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am using a Java IDE (IntelliJ).
I want to read in an array of integers (nums) and then a single integer (target).
I found that using CTRL-D to end the array input will reset stdin, so thought I should read the array as a string (to parse later) and then read the integer (target).
But I am unable to get Scanner to read the second integer.



OUTPUT


input the array of integers
1 3 5
4^D
s 1 3 5
input the target integer
target -1
Process finished with exit code 0



 
Sheriff
Posts: 4646
582
VSCode Eclipse IDE TypeScript Redhat MicroProfile Quarkus Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You could just trying to read integers from the scanner - if the next token can not be transformed to an int, then Scanner#hasNextInt will return false.

 
Anil Philip
Ranch Hand
Posts: 662
3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Ron McLeod wrote:You could just trying to read integers from the scanner - if the next token can not be transformed to an int, then Scanner#hasNextInt will return false.


Thank you for your reply.
I want to read the array of ints and then a target int.
I did try hasNextInt() and nextInt() but was unable to read the separate field, the integer 'target'.
Are you able to do that?



OUTPUT

input the array of integers
1 3 5 .
al [1, 3, 5]
input the target integer
target -1
Process finished with exit code 0


 
Ron McLeod
Sheriff
Posts: 4646
582
VSCode Eclipse IDE TypeScript Redhat MicroProfile Quarkus Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Maybe this? :

 
Marshal
Posts: 79971
396
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I prefer to use a utility class to wrap a Scanner for keyboard input; you can prevent exceptions if the entries are of the wrong format.

Anil Philip wrote:. . . I found that using CTRL-D to end the array input will reset stdin. . . .

No, don't use ctrl‑D; it can close System.in, leaving you with no way to reopen it. And it's probably better to call it System.in rather than stdin when writing Java® please.
I think I would use a Stream (some of these methods were not available in Java8).
  • Line 1 creates the Scanner
  • Line 2 issues instructions
  • Line 3 declares an array to be produced by the code following.
  • Line 4 takes all the tokens entered and creates a Stream<String> to manipulate them.
  • Line 5 uses a λ expression to test the input by passing it to a new Scanner object. That may seems slow, but if it takes 1 second to enter a number on the keyboard, and maybe 0.05μs to create the Scanner, you haven't got any problems. The hasNextInt() method will return false if you pass anything not an int, and then takeWhile() will finish populating the Stream.
  • Line 6 uses the mapToInt() method to create a special Stream for ints only. Note I have passed a method references to this method and made a mistake writing the code.
  • In line 7, this method directly produces an int[].
  • To get to line 8, enter one token that is not an int, and you can then read the number. You will have to push the enter key to get all the tokens processed.
  •  
    Campbell Ritchie
    Marshal
    Posts: 79971
    396
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Anil Philip wrote:. . . I want to read in an array of integers  . . .

    Don't confuse arrays and array lists. A list isn't an array, and you are creating a list.
     
    Anil Philip
    Ranch Hand
    Posts: 662
    3
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Ron McLeod wrote:Maybe this? :


    Thanks!
    I was trying to use skip() but I did not know how to specify CTRL-D in the pattern.
    Your method of using dot to end input, and using next() to skip input, works.
    Thank you!
     
    Anil Philip
    Ranch Hand
    Posts: 662
    3
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:
    I think I would use a Stream (some of these methods were not available in Java8).


    Thank you for the streams version; it is instructive. I was unable to figure out how I would do it using streams!
    But it seems inefficient to create a new Scanner for each input integer.
     
    Anil Philip
    Ranch Hand
    Posts: 662
    3
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:passing it to a new Scanner object.


    Is there a way to reuse the Scanner instead of creating a new one each time?
    When I try your version, I get a ConcurrentModificationException



    input the array of integers
    1 3 5 . 4
    Exception in thread "main" java.util.ConcurrentModificationException
    at java.base/java.util.Scanner$TokenSpliterator.tryAdvance(Scanner.java:2851)
    at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
    at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:575)
    at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260)
    at java.base/java.util.stream.IntPipeline.toArray(IntPipeline.java:562)
    at two_sum.TwoSum_Scanner.main(TwoSum_Scanner.java:14)

    Process finished with exit code 1


     
    Ron McLeod
    Sheriff
    Posts: 4646
    582
    VSCode Eclipse IDE TypeScript Redhat MicroProfile Quarkus Java Linux
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    There is probably a better way to work with a stream of tokens, but this is my first thought:
     
    Anil Philip
    Ranch Hand
    Posts: 662
    3
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Ron McLeod wrote:There is probably a better way to work with a stream of tokens, but this is my first thought:


    Does not compile using intValue.

    java: incompatible types: invalid method reference
       method intValue in class java.lang.Integer cannot be applied to given types
         required: no arguments
         found:    java.lang.String
         reason: actual and formal argument lists differ in length



    Using parseInt, it will compile but then

    Exception in thread "main" java.lang.NumberFormatException: For input string: "."




     
    Saloon Keeper
    Posts: 10930
    87
    Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
    • Likes 1
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
     
    Campbell Ritchie
    Marshal
    Posts: 79971
    396
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Anil Philip wrote:. . . Is there a way to reuse the Scanner instead of creating a new one each time?

    No. You are looking at the token previously read, not the next token. I have already told you, the overhead of creating multiple objects is tiny compared to the time it takes to enter numbers.

    When I try your version, I get a ConcurrentModificationException . . .

    That is because you are not using what I wrote. You are trying to do two things simultaneously with the Scanner, which it doesn't like. I have only seen that exception with Iterators . . . . but a Scanner IS‑AN Iterator<String>.
     
    Campbell Ritchie
    Marshal
    Posts: 79971
    396
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Ron, I am afraid I think the parsing method is using exceptions for flow control. Not something I like.
    AP: Since Scanner#tokens() never includes null, that takeWhile() call will never terminate the Stream, and you will suffer an exception.
     
    Carey Brown
    Saloon Keeper
    Posts: 10930
    87
    Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    A variation that (mostly) avoids using exception handling for flow control.
     
    Campbell Ritchie
    Marshal
    Posts: 79971
    396
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    That isInt() method looks like the sort of thing Scanner does already.
     
    Did Steve tell you that? Fuh - Steve. Just look at this tiny ad:
    Gift giving made easy with the permaculture playing cards
    https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
    reply
      Bookmark Topic Watch Topic
    • New Topic