• Post Reply Bookmark Topic Watch Topic
  • New Topic

scan.hasNextInt doesn't always wait for input  RSS feed

 
Ranch Hand
Posts: 205
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have a method to allow the user to choose from a menu and the scan.hasNextInt waits for input the first time I call it but if I call it again the scan.hasNextInt doesn't wait for input.
The output for the code below is:
Enter a number.
1
leaving
choice = 1
Enter a 2nd number
No Input
leaving
choice = 0

Any help would be appreciated.

 
Ranch Hand
Posts: 250
1
Chrome Eclipse IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What is the purpose of the line scan.nextLine()? Also, your if/else statement doesn't seem to be necessary.
 
Bartender
Posts: 321
24
Eclipse IDE Firefox Browser
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Kendall,

Welcome to the Ranch!
In the future, it would be great if you could use Code Tags (← Not sure how? Click the link) to increase the readability of your code.

Now, I notice you are closing the Scanner(System.in). The System.in is a bit of an unique resource, as once closed it cannot be reopened. If you are closing it because Eclipse is telling you to, ignore it. The advisements in Eclipse are suggestions only. If this was a stream or file you had opened, you would want to close it, but the System.in is special. Try removing the close statement and see what happens.

Just a general comment about the method organizations. You really should think about reorganizing your main method. Normally, the main method should only have a few lines of code to instantiate the application and run it. Everything else should be delegated to other methods and/or classes. Speaking of instantiation, I'm not sure if making everything static is a good idea. Static methods are usually used more for Helper/Utility purposes, such as the static Integer.parseInt() method. If the class was instantiated, you could use a Try With Resources block to close out the Scanner during application shutdown.

Also, I don't see any point in having the menuChoice accept a parameter. Perhaps there is more to the code you didn't post, or are planning to add, but you do notice the 3 value you are passing to menuChoice is never used?
 
Marshal
Posts: 56608
172
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Chris R Barrett wrote:Hi Kendall,

Welcome to the Ranch!
Agree Welcome again

In the future, it would be great if you could use Code Tags . . .
Since you are new, I have added the code tags. Doesn't the post look better It will look even better when I correct the mistake I made with the code tags.

Your use of Scanner looks complicated. And when things are complicated, things go wrong. In my opinion the correct way to use Scanner is to wrap it in a utility class but you are probably at the stage where you haven't got the time to write utility classes, so let's find a simpler way to do it. I shall suggest the simplest way I can think of.
  • 1: You don't need several Scanners. You only need one. Create it at the start of the program and use it throughout.
  • 2: As you have already been told, you mustn't close a Scanner pointing to System.in. Or anything else pointing to System.in. Or anything pointing to System.out or System.err. If you close those Streams, you can never reopen them.
  • 3: If you want an int and the user enters something different, you will suffer an Exception. For the time being forget about Exceptions and make sure you only enter the right input.
  • 4: Now you can do what it says in the Scanner documentation:
  • And you can simply add things to that, like this:-Armed with what Rob Spoor told me a long time ago about Scanner, Prasanna Rahman wrote herself a little utility class which gets ints from the keyboard. Look here. That method will never throw an Exception and will loop until you enter a correct int.
     
    Kendall Ponder
    Ranch Hand
    Posts: 205
    4
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Thanks for the help! Sorry about not using the code tags, I will do so in the future. Not closing the scanner solved the problem, I thought I was being good by closing it, I never would have figured that out. This was not the actual code I was using in my program, but was just some code to isolate what the problem was. That is why the code like the if statements don't make sense, I stripped out all of the extra stuff. In regards to only having one scanner open in the program, do you mean I should declare a scanner in a class and make it available everywhere? Thanks again! P.S. Do I click on the +1 button to say I like an answer?
     
    Kendall Ponder
    Ranch Hand
    Posts: 205
    4
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Joel Christophel wrote:What is the purpose of the line scan.nextLine()? Also, your if/else statement doesn't seem to be necessary.

    I was using it to get rid of the end of the line characters left by scan.nextInt(). Is that not necessary?
     
    Campbell Ritchie
    Marshal
    Posts: 56608
    172
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Kendall Ponder wrote: . . . I was using it to get rid of the end of the line characters left by scan.nextInt(). Is that not necessary?
    No. Only if you change the delimiter might there be any point in calling nextLine.

    The default delimiter for a Scanner is whitespace. You can read about it in the Scanner documentation. If you have a token followed by a line end character, that line end character counts as whitespace. So pushing the enter key counts as whitespace. It counts as part of the space between successive tokens, so a nextLine call will not be necessary.
    If you enter
    123 456 789
    or
    123 456
    789
    and call nextInt() thrice, you will get the same input. But if you call nextInt() twice, nextLine() and nextInt() you will get different input. In the first instance the 789 will be lost. So not only is the nextLine call unnecessary, but in certain unusual circumstances it might even be harmful.
     
    Kendall Ponder
    Ranch Hand
    Posts: 205
    4
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Campbell Ritchie wrote:
    Kendall Ponder wrote: . . . I was using it to get rid of the end of the line characters left by scan.nextInt(). Is that not necessary?
    No. Only if you change the delimiter might there be any point in calling nextLine.

    The default delimiter for a Scanner is whitespace. You can read about it in the Scanner documentation. If you have a token followed by a line end character, that line end character counts as whitespace. So pushing the enter key counts as whitespace. It counts as part of the space between successive tokens, so a nextLine call will not be necessary.
    If you enter
    123 456 789
    or
    123 456
    789
    and call nextInt() thrice, you will get the same input. But if you call nextInt() twice, nextLine() and nextInt() you will get different input. In the first instance the 789 will be lost. So not only is the nextLine call unnecessary, but in certain unusual circumstances it might even be harmful.


    Thanks for the info. I have seen the advice of adding the nextLine() more than once on another help site. I appreciate the corrected information.
     
    Campbell Ritchie
    Marshal
    Posts: 56608
    172
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Using nextLine twice works if you are sure there is a line end in the right place.

    And … you're welcome
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!