• Post Reply Bookmark Topic Watch Topic
  • New Topic

Scanner nextInt and nextLine  RSS feed

 
John Losty
Ranch Hand
Posts: 76
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
code:



Output:


I don't understand why this program after it displays the line :"Enter 2nd string, Enter 'quit' to exit "doesn't wait for the user to enters a String ?
 
Knute Snortum
Sheriff
Posts: 4087
112
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It has to do with the way Scanner works, and it is very confusing. Basically, nextInt does not consume the CR at the end of the input and leaves it in the buffer. This is fine if the next call is to nextInt as it will skip pass the CR to find the int. But with nextLine it is looking for the CR to terminate the line. So a nextLine after a nextInt "skips" the input and interprets the CR as an empty line.

The way around it is to call next (Edit: my class uses nextLine) after the nextInt, or create a class to do it for you.
 
John Losty
Ranch Hand
Posts: 76
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
so:
nextInt() finds int until CR but it doesn't consumes CR
nextLine() copies everything until CR includin CR

so what next() does?
 
Knute Snortum
Sheriff
Posts: 4087
112
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My understanding is that next gets the next token -- delimited by separators -- and nextLine consumes the entire line. But if the separators are whitespace, which they are by default, then this distinction isn't very great.

I would advise playing with it to get the best behavior. Also, I would create a class that takes care of all of this if you will be writing many console programs.
 
Henry Wong
author
Sheriff
Posts: 23284
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
John Losty wrote:so:
nextInt() finds int until CR but it doesn't consumes CR
nextLine() copies everything until CR includin CR

so what next() does?


The nextInt() method grabs the next token, but it doesn't consume anything after the token.... meaning any delimiters, following tokens, and/or including the CR. It also processes the token to be an integer, throwing an exception if it fails.

The nextLine() method grabs everything from the current position to the CR -- leaving the next position at the beginning of the next line.

The next() method grabs the next token, just like the nextInt() method, except it doesn't parse it for an integer. It simply returns the next token.

Henry
 
Winston Gutkowski
Bartender
Posts: 10573
65
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Knute Snortum wrote:My understanding is that next gets the next token -- delimited by separators -- and nextLine consumes the entire line. But if the separators are whitespace, which they are by default, then this distinction isn't very great. I would advise playing with it to get the best behavior...

Great advice, but I have to stick my oar in here (and I know I'm on a hiding to nothing if Campbell gets involved ):

<ScannerRant>

This is why I don't like Scanner - especially for keyboard input.

Why should I have to "play around" with a class to understand how it works?

@John - My advice when using Scanner for keyboard input (and there'll be LOTS that disagree with me):
Use nextLine(). ALWAYS. It almost never throws an Exception - and if it does, there's probably nothing you could have done about it anyway - and it returns you a String.

And It DOES consume the CR you get when you hit the ENTER key, so it's always leaves the Scanner in a state to accept another call to newLine().

OK, so now you have a String. What is it supposed to be?
  • A Number? Simple: use Integer.parseInt(), or Double parseDouble(), or new BigInteger(String), or any one of the 'valueOf(String)' factories the bods at Sun gave you for wrapper classes...
  • A Date? Simple: Use SimpleDateFormat.parse().
  • A pattern of some kind? Simple: Use String.matches().
  • Something else? Call the custom routine you wrote to turn a String into a virtual machine that makes tea for you (or whatever).

  • Alright, so it might take a few extra lines of code, but now you're in control of the process; not some useless f@$!%# class that can't make up it's mind whether it likes CRs or not.

    </ScannerRant>

    Having said all that (I'm feeling better now), I think that Scanner's designers hearts were in the right place. They just made a pig's ear of it.

    Happy New Year everyone.

    Winston
     
    Piet Souris
    Rancher
    Posts: 1984
    67
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Winston Gutkowski wrote:
    @John - My advice when using Scanner for keyboard input (and there'll be LOTS that disagree with me):
    (...)

    You're not alone in this; I agree.

    And a Happy New Year to you too!
     
    Campbell Ritchie
    Marshal
    Posts: 55789
    164
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Happy New year too

    I have been too busy to get involved earlier, I am afraid. A long time ago Winston described the real problem with Scanner: Sun/Oracle didn't provide a good tutorial about how it works. The books all say that nextLine returns the next line, which it doesn't. Yes, nextInt parses the next instance of numbers as an int, next returns the next “token”, delimited by the current “delimiter”, as Knute said. And nextLine returns from where you are to the next line end characters (might be CR might be LF might be some other sort of line end). Since line end characters are included in the default “delimiter”, as Knute also said, they are not consumed by next or nextInt. You can see the default delimiter like this:-At least I think that will work.
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!