William Varner wrote:Also, do y'all recommend doing a "sc.nextLine()" after scanning in an int? I was taught that this was very important.
No, I don't recommend that. There is one situation where a nestLine() call is needed. See this old post of mine.
The nextLine() method is not well documented in many places; some books suggest it reads the next line, but the link I gave you makes it clear that isn't correct. It returns the remainder of the current line; if the current line contains something which has been read, there is a risk that nextLine() will read an empty line from the rest of the line, and even better, the following line, which you actually want to read, is read as something else causing (if you are lucky) an exception, or (if you are unlucky) putting the information into the wrong locations in your program. So, as you will see from the old post, you need to call nxxtLine() after nextSomethingElse() and before the nextLine() call that you actually want.
If you call nextLine() after every nextInt() call, you will slow down execution because you are using twice as many calls and you will lose the flexibility of Scanner. It is possible to write a line like this:-
123 456 789 and call it with any three calls to read numbers, in any order. If you follow the first call with nextLine(), you will lose the 456 789 part. Example
Actually, if you are using the keyboard, I think that is all wrong too. What I did was to write a utility class, so I can writeBut my utility class only works for keyboard input. It is so written that is never throws an input mismatch exception.
Surprisingly big amount of people are confused about scanner's functionality.
Here is how I was researching this area for myself in order to understand it.
- Let's omit Java ceremony and just assume we start from here:
- First thing to understand is, that default scanner's delimiter is a white space character.
1. Now we want to extract number 2. So we call:
And there is still more to read in this text string...
2. If we were to call:
That would return "heads", because that is the next token after the default delimiter (white space character) has been passed. If we were to call again same method, that would return "are" and so on...
2.1. If we were to call (right after the step 1):
That would return the rest of the current line (default delimiters aren't skipped), which ends right after the line separator "\n", excluding line separator itself, meaning, would return: " heads are better than 1."
That is what small part of documentation says:
JavaDocs of nextLine() wrote:* This method returns the rest of the current line, excluding any line
* separator at the end. The position is set to the beginning of the next
3. Having said that, there would be still some data left to read in the text string, and that would be: "CodeRanch.com is great."
4. Now, there are only few options left:
[option 1] either call in.next() (at most 3 times) so it would tokenize (based on default delimiters) and return from calls of in.next(): CodeRanch.com is great.
[option 2] call simply in.nextLine() which would return: " CodeRanch.com is great." and again as documentation says, after such call would be:
JavaDocs of nextLine() wrote:* The position is set to the beginning of the next line.
Since there is nothing else to read, end of story, exception would be thrown attempting to read further.
[option 3] mix of these two above.
It is worth mentioning, that next() and nextLine() differ in that way, that next() tokenize based on default or set delimiter(s), while nextLine() ignores them and just reads the rest of the current line.
Quick example of next():
All tokens would be read by only 2 calls of next() method, because "\n" isn't part of default delimiter and I did not set it up as such (while for nextLine() "\n" would mean end of the current line):
By printing that with print(), it would print (on separate lines):
I think spending about 15-30 minutes trying to read in and print in various ways would eliminate most of confusion about the Scanner people have.
THIS discussion was posted yesterday. It involved reading a record from a file laid out as 5 separate lines of input. After each non-nextLine() call the OP put a call in to nextLine(). So, the very last item in a record was a double with a call to nextDouble() followed by a call to nextLine(). This worked for all the records except the last one because there was no new-line character following the last double, so it threw a NoSuchElementException.
So here we have another case where always adding a call to nextLine() causes a failure.
I'm the outlier here. For getting input from the keyboard, the only function I use from Scanner is nextLine(). This is for two reason. One, I want to be able to detect when the user only presses <Enter>. I use this behavior to enter default values.
What is the meaning of the Universe? (default = 42):
The other is that if you use nextInt() or any of the other nextXxx() functions you can run into this problem:
What is your age? 6e
Here the user has slipped and accidentally typed 6e instead of 64. I don't want the program to accept 6 and leave e in the buffer. I want the program to ask for the age again.
Campbell and I do agree on one thing: you really need to write a utility class to wrap Scanner (or maybe BufferedInput?). Add prompting and validation and you have a handy class. I call mine Inputer and it's freely available on my GitHub repo.
All things are lawful, but not all things are profitable.
posted 4 months ago
Knute Snortum wrote:. . . . I don't want the program to accept 6 and leave e in the buffer. I want the program to ask for the age again. . . . .
It won't. It will throw an exception. If you want to avoid the exception, you need the loop which Rob Spoor taught me ages ago:-I have that method overloaded so as to accept different error messages for incorrect input. I also have the method overloaded to accept only values in a certain range, but you have to throw an illegal argument exception if !(max > min). I have not therefore worked out how to supply a default. Lines 21‑22 can be swapped.
There are various possibilities for reading a whole line; the following is one of them:-I have found no defence against people who use ctrl‑D/ctrl‑Z and close System.in. Eclipse users might wish to add a @SuppressWarnings annotation to line 6. I have not worked out how to make such a class threadsafe. The \u2019 escape is a posh apostrophe.
All of the world's problems can be solved in a garden - Geoff Lawton. Tiny ad:
RavenDB is an Open Source NoSQL Database that’s fully transactional (ACID) across your database