• 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
  • Ron McLeod
  • Paul Clapham
  • Rob Spoor
  • Liutauras Vilda
Sheriffs:
  • Jeanne Boyarsky
  • Junilu Lacar
  • Tim Cooke
Saloon Keepers:
  • Tim Holloway
  • Piet Souris
  • Stephan van Hulst
  • Tim Moores
  • Carey Brown
Bartenders:
  • Frits Walraven
  • Himai Minh

sometimes I must press enter twice, others I do not have to

 
Ranch Hand
Posts: 274
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello, I am looking to find the reason as to why my inputs are all messed up. I run the program, and sometimes I have to press enter just to get the menu to display, sometimes it displays without issue. All of my methods do the same thing, sometimes I have to enter the menu choice twice, other times I do not. I have tried scanner.nextLine(); however that does not work as sometimes I need to eat whats in the buffer, other times I do not, what could be causing this great annoyance?

 
Saloon Keeper
Posts: 8449
71
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Where is the createTesterUser() method?
Your 'scanner' variable should be declared as 'static final'.
Are you also creating a scanner object in ANY of your other classes (e.g. FacebookUsers)?
You are randomly adding scanner.nextLine() calls without knowing if you need them. The various 'yum yum' ones you have right now are not needed.
The only call that can leave stuff pending in the input is scanner.nextInt(). Fix the problem there.
 
kennith stomps
Ranch Hand
Posts: 274
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Great help, I was not aware of nextInt being the only call that can leave stuff pending, or even that something pending being a cause to such a problem. What would you call an issue like this? A stuff left pending issue? Or is there some better term I could use
 
Bartender
Posts: 732
10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There are many things that can "leave stuff pending". For example, a call to nextInt() will leave all of the input pending if the input cannot be interpreted as an int If the user types "4 5", the Scanner will read the 4 and leave the 5 pending for the next read
It is probably best to first use hasNextnt() to ensure that an int can be read.
 
Ranch Hand
Posts: 218
5
MS IE Notepad Suse
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
the main problem here seems mis-understanding and therefore mis-using of scanner class when using it to read console input

a regular os-level console (as cmd on windows or any tty-shell on linux) use line based logic in use with java

that means: if you somewhere want to read input from console it is all delievered as one line - so its best to only use nextline() and parse the input yourself

usin any other method of scanner only makes sense as tokenized reader when handling file-input with a defined format - all thought datainputstream maybe preferred in such cases - renders scanner almost useless and only raises more confusion as intented when this class was designed


that's just my opinion - but i'm almost only use datastreams in my codes as they fit my needs best
 
Marshal
Posts: 73751
332
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Matt Wong wrote:. . . if you somewhere want to read input from console it is all delievered as one line - so its best to only use nextline() and parse the input yourself

Disagree. If you want to use a Scanner, you can ensure it will only pass the required input. If you are going to read whole lines, why bother with Scanner? Use a buffered reader reading from System.in.

Scanner is a well‑designed class, and poorly documented. As Winston Gutkowski said a long time ago, there are hardly any good tutorials about it. Search my posts about it; there is a technique Rob Spoor taught me alon gtime ago to reject incorrect input.

. . . file-input with a defined format- all thought datainputstream maybe preferred in such cases . . .

Input Streams for text files? If you are going to use something other than Scanner for a text file, again use a buffered reader.
 
Sheriff
Posts: 7111
184
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Matt Wong wrote:if you somewhere want to read input from console it is all delievered as one line - so its best to only use nextline() and parse the input yourself


Campbell and I disagree over this.  I wrote a whole console inputting class call Inputer with only Scanner#nextLine().

Campbell Ritchie wrote:If you are going to read whole lines, why bother with Scanner? Use a buffered reader reading from System.in.  


I hadn't thought of that -- but this is why Campbell is my senior here.  The thing I couldn't do using nextXxx() was get just an <Enter>, which is critical to Inputer.  I'll have to try BufferedReader for reading the keyboard sometime.
 
Campbell Ritchie
Marshal
Posts: 73751
332
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Knute Snortum wrote:. . .  I wrote a whole console inputting class call Inputer with only Scanner#nextLine().

I have a similar class which usually doesn't use nextLine().

. . . I hadn't thought of that  . . .

That is why we have this sort of forum. We all learn things from the discussions here. I have learnt lots and lots from being disagreed with here, which I am very grateful for.
 
Matt Wong
Ranch Hand
Posts: 218
5
MS IE Notepad Suse
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think misunderstanding just happend again.
To further explain myself: if you run a console style code reading from System.in, the main problem is you can't tell the console what input to read as an os-console won't pipe input to Java unless a crlf is triggered by hitting enter.

So, when I expect only an int - I can't tell the os-console to just get me that int but discard the crlf. And that's what most beginners don't understand correctly and therefore make mistakes.

Sure, when I enter a space separated list I can get them with just next() instead of doin a split on a string read by line - but i would still end up with one last empty call to clear the crlf from the input buffer. And for me - it's just another way - but a redundant one as console class or your mentioned buffered read works as easy - you only have to add the parse calls yourself.

btw: I thought about reading binary data with datastreams - not text
 
Campbell Ritchie
Marshal
Posts: 73751
332
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What't crlf? That is something which only occurs on a Windows® box.
What follows depends on whether you are getting the text directly from the terminal or whether you are somehow processing it. As you said, the terminal returns text. You can pass a line readingto three consecutive nextInt() calls and receive the ints, as long as you have a suitable delimiter set on the Scanner. The default delimiter is any amount of whitespace. As you said, the teerminal/console passes that line as a line of text, not threee numbers, and it is for the Scanner object to translate it into the three numbers.
Remember that a Scanner is described as

A simple text scanner . . .

which can also be misunderstood. It doesn't mean that Scanner is simple, as I once thought; it means it scans simple text. That means ordinary text; it is not intended for HTML tags or XML tags.
Anyway, as you said, the terminal/console passes a line of text in the form of text and a Scanner parses it from the start to the next delimiter. Except for the nextLine() method which reads from the current position to the next line end sequence and moves on to the next line, thereby discarding the next line end sequence. If the text has been read as far as the end of the current line, nextLine() will find the remainder of the current line is empty or all whitespace and return that. Yes, you are in a quandary here; you cannot read the three ints until you push the enter key, but that leaves the remainder of the current line too short to be of any use. The simplest solution, but not necessarily the best solution, to this problem is to call nextLine() twice.
If you call nextXXX() not nextLine() you can put as many blank lines between inputs as you like; remember the line end sequences count as whitespace. The Scanner object will resume scanning from the next non‑whitespace character; if that token isn't appropriate to its requirements, it will throw an exception.
 
Knute Snortum
Sheriff
Posts: 7111
184
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Scanner is great for scanning text files, but I don't like it for getting input from the keyboard.  The reason I wrote the Inputer class is that I wanted something that would handle prompts, error messages, default values, custom validations, and all the error processing bundled into one object.  You just can't do that easily with Scanner.
 
Matt Wong
Ranch Hand
Posts: 218
5
MS IE Notepad Suse
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, as explanatory your post is for others might using Scanner class, for me it's still a class I wont use it in my codes.
Also, sorry for bein on the direct way again, wich I know you don't much like on me, you may didn't read my post carefully enough. I explicit mentioned the issue an os-console (and for, this is not limited to windows' cmd.exe but also to standard bash-shell on linux) processes input reads different than most beginners thinik it would. That's it - if you hang in any sort of System.in.read() by any way, it won't return until the console passes the data input by the user is piped to it. And this only happens the very moment you hit return on the console wich triggers a stream of "<what ever the user input>" + os-console line delimiter (on windows \r\n, on unix \n, on mac it was just \r - but I think that changed). So how ever how much data is read through wich class, it can only be something between "<nothing at all>" and "<what ever user input>" plus always the line delimiter.

What most beginners falsely think Scanner would do: When they print a numbered menu and want the get the users choise the call nextInt() to get the entered number.
How Scanner class actually works: As the console not only delievered the entered number but also the line delimiter - the nextInt() only processes the integer but would leave the delimiter still lying in the buffer waiting to be processed by any suiteable method like simple next() or nextLine().

And exactly that's what's the main issue in the code of OP: mis-using of Scanner class by most likely lack of knowledge how it really works. I didn't bothered to work through the whole code - but lets look at only the first choice:

- the menu is printed
- nextInt() tries to process the next available integer - as the buffer is empty at that point when run for the first time it somehow gets down to System.in.read() wich blocks and wait for input from console
- the user inputs some number and to "submit" it to the nextInt() RETURN has to be triggered
-- now what's really happens is, that the terminal sends the entered number PLUS the line delimiter
-- nextInt() now processes the available integer, returns it, and the line delimiter is left alone in the buffer waiting to be processed
- switch triggers listUser(), breaks, and loop wraps around
- now nextInt() is hit again - but as there still some data left in the buffer - they get processed first - wich is the line delimiter - wich obvious can't be parsed into an integer - wich, according the doc, should throw an InputMismatchException - IDK, IDC, but I guess as OP didn't mentioned it, I guess line delimiter just gets discarded silently and further processing starts from top of the list

A possible better approach could had been: constantly using Scanner.nextLine() and add Integer.parseInt() (or what ever input is expected). This way, it is ensured that the full line piped by the console gets consumed, including the line delimiter, nothing is left in the buffer, and with correct exception handling it can be ensured it's inputted what is requires. In this very case - it even doesn't matter if using Scanner(System.in).nextLine() or BufferedReader(InputStreamReader(System.in)).readLine() - wich I guess is done by Scanner internally, or some similar.

Anyway - it's not gettin us futher fighting about personal opinions about Scanner class - the forum is to help the ones asking for it - so let's get back to it:

The OP asked why some inputs are "eaten" and has to be entered twice - the solution: wrong usage of Scanner nextXXX() methods wich needs to be corrected or can be done in another way.

I just added my personal comment about this kind of "mistake" happens to many beginners as they simply mis-understand how Scanner really works internally and mostly miss the point, that the nextXXX() methods may not work as the think they should but leavy something in a buffer wich gets processed the nxt time one of the nextXXX() methods gets called. Also I mentioned, for me the DataInputStream class fits way better for reading binary formats or data I've written out by DataOutputStream on a Socket connection.

Could the code improved by just replacing all of the Scanner with another input method? Maybe. Could or Would the solve OPs issue? Possible. Does it make sense in anyway of learning and letting OP the chance to discover his own way of console input? no way at all.
Allthough it all gets down to somewhat like System.in.read() - there so many possibilities built into SE API - anyone should get the chance to get used to what one likes best - we can only help on errors and mistakes to get the chosen way right.
 
Campbell Ritchie
Marshal
Posts: 73751
332
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Knute Snortum wrote:Scanner is great for scanning text files, but I don't like it for getting input from the keyboard.  . . . .

Sorry I didn&apost;t have the time to reply last night, but I think we agree on that point; once you have created a utility class to deal with the vagaries of Scanner, which as MW points out are badly documented in many places, you find keyboard input so much easier and more reliable. I think my KeyboardInputs class differs rather from your Inputter class, but I think we both find such classes much easier to use from the keyboard than a plain simple Scanner. The reason is that it is possible to ensure consistent format of the contents of a text file, so nextInt() actually finds an int, but you can't be sure there won't be errors when entering data live from the keyboard.
I agree with MW that beginners aren't taught to use Scanner properly; in fact I suspect most teachers think nextLine() means, “read the next line,” rather than, “move to the next line”. The fact that the default delimiter is 1+ whitespace characters means a line end sequence can be incorporated into the current delimiter sequence, so people think something similar will work for nextLine().
I can't see that the read() method is any good. It is a low‑level method which would need all the inputs casting to a char so as to reconstruct the text before parsing it. If you simply want to read line by line, why not use the old method with BufferedReader#readLine()?
 
When it is used for evil, then watch out! When it is used for good, then things are much nicer. Like this tiny ad:
the value of filler advertising in 2021
https://coderanch.com/t/730886/filler-advertising
reply
    Bookmark Topic Watch Topic
  • New Topic