• Post Reply Bookmark Topic Watch Topic
  • New Topic

Using Scanner.nextInt with Scanner.nextLine  RSS feed

 
Kendall Ponder
Ranch Hand
Posts: 205
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The following code is to illustrate the problem I have in my real code. Class3 is a utility class which has two methods to get input from the user. The method getInt() returns an int and getInput() returns an entire line.


When I use getInt() in the following code everything works fine.

The integer entered by the user is printed to the console followed by whatever text the user enters next. But if I try to use the Class3 static getInput() method with the getInt() method I run into problems.

The interger the user enters is printed out but the second print prints an empty String before the user has a chance to enter any text. I assume what is happening is the nextInt() method leaves the end of line character which the nextLine() method immediately reads. My question is why doesn't that happen in the first code? Why does having a second Scanner variable pointing to the System.in change the behavior? Any help would be appreciated!
 
Tushar Goel
Ranch Hand
Posts: 934
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Problem is with the nextInt method. Go through this old post. Campbell Ritchie told me about this.
 
Campbell Ritchie
Marshal
Posts: 56518
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
… and tell us what your book says nextLine() does. I have yet to see a good explanation of it. Except possibly in my posts I wrote a method for a utility class here, and Prasanna Raman found where my dreadful mistake was. You must read to the end of that thread.
 
Liutauras Vilda
Sheriff
Posts: 4914
334
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Kendall,

I remembered and managed to find: in Head First Java, page 112, there is a very nice written utility class for user input.
Didn't compare it with Campbell's written method, might he came up with something better, well, you can compare

Might some ideas you'd find useful to use in your own utility class.
 
Campbell Ritchie
Marshal
Posts: 56518
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I haven't got my Head First with me at the moment, but I shall try to remember to look at it later. Thank you for the information
 
Liutauras Vilda
Sheriff
Posts: 4914
334
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:I haven't got my Head First with me at the moment, but I shall try to remember to look at it later.
Well, I could guess your opinion based on your previous posts

But beside that, OP is going to read not only the string lines, but also an int's, so Head First Java utility class would become dreadful I realized now. Since parsing would be needed for int's.
I think OP is right by writing his own utility class, but still, I can see some useful tips in HFJ version could be looked at.
 
Campbell Ritchie
Marshal
Posts: 56518
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
We used to have to write this sort of thing, which became redundant when Java5 came out 11 years ago.Unlike the version Rob Spoor taught me, that risks number format exceptions. Rob's version can be written so as to guarantee no Exceptions, with one notable exception. That has to do with reading a numeric value within a particular range, ≤ max and ≥ min. I shall leave you to work out what circumstances might lead to an Exception.
 
Liutauras Vilda
Sheriff
Posts: 4914
334
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You're right, not arguing about that, reading int's would be old fashioned way. For reading the strings, HFJ proposed class would still do job good.
I shall leave you to work out what circumstances might lead to an Exception.
< -2_147_483_648 .. > 2_147_483_647

// I am sure you know why there is a private constructor.
To make sure no other classes except nested would create ever an instance.

Actually I should be more careful when referring to HFJ, as it is quite old book.
Thanks Campbell for pushing train back on the rails, and sorry Kendall for confusing you - it is hot as in hell in England in these days.
 
Kendall Ponder
Ranch Hand
Posts: 205
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Unlike the version Rob Spoor taught me, that risks number format exceptions.

But this version leaves the new line so it causes problems when you mix it with Scanner.nextLine(). Should I add a scan.nextLine() to it as follows:


 
Kendall Ponder
Ranch Hand
Posts: 205
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I understand the problem with nextInt leaving the newline, but why does it not cause a problem when you have two Scanner variables like I do in the first example? If the utility method declares a private Scanner variable the problem with leaving the newline goes away. Both of the following code segments work:

All the methods in one class with each method having a private Scanner variable:


or using a utility class where each method has a private Scanner variable. Note that if you uncomment the final Scanner variable in Class3 and remove the private variables from the methods the newline problem reappears so I don't think it matters if your Scanner variable is static. It looks like any information left in System.in by a Scanner method called by a Scanner variable is discarded when a different Scanner variable calls a Scanner method. Is that true?


 
Campbell Ritchie
Marshal
Posts: 56518
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am not at all convinced you should use multiple Scanners for System.in. Use one, which should be a private static final field in your utility class. By the way: those are not private variables, but local variables to the different methods. Never close a Scanner using System.in.

Beware: Unless you put locks or other synchronisation on, the keyboard input classes are not thread‑safe.

I am not sure I think the example in HJF page 112 is actually a utility class at all. It does not have the usual features I have come to expect, viz all static members. It also uses the older technique with buffered readers. If you use a Scanner you don't have to worry about Exceptions. If you really want to see an Exception you can write this sort of thingChances are it will print “null”. Don't try to throw such an Exception until you are sure it isn't null; if you do you will suffer a null pointer Exception.
 
Kendall Ponder
Ranch Hand
Posts: 205
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am not at all convinced you should use multiple Scanners for System.in. Use one, which should be a private static final field in your utility class

Sounds good to me. So should I add the scan.nextLine() to my getInteger() method so I can use it in conjunction with a method which uses nextLine()?
 
Campbell Ritchie
Marshal
Posts: 56518
172
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Kendall Ponder wrote: . . . So should I add the scan.nextLine() to my getInteger() method so I can use it in conjunction with a method which uses nextLine()?
No.

Any use of nextLine should be associated with nextLine. If you use nextInt and follow it with nextLine you cannot write this sort of thing:-
Please enter three numbers: 123 456 789
Look for this old post (as mentioned earlier), which shows exactly what not to do. If you scroll down you find what the error is and can correct it. Note that method returns the first “nextLine” which does not consist wholly of whitespace. That is done with the trim() call.

If you pass min greater than max to a method requiring a range, then either i < min or i > max. That means if you are checking for a value in that range, it will continue to ask for new input for ever (or until your hardware wears out and the computer stops working). The correct answer is to add this sort of thing near the beginning of the method… and that is how you are going to get an Exception.

HFJ might be an old book but it is still good.
 
Kendall Ponder
Ranch Hand
Posts: 205
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Got it. Thanks!
 
Campbell Ritchie
Marshal
Posts: 56518
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You're welcome
 
Consider Paul's rocket mass heater.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!