• Post Reply Bookmark Topic Watch Topic
  • New Topic

Problems while testing Scanner class  RSS feed

 
Badr Ibrahim
Greenhorn
Posts: 5
Eclipse IDE Redhat
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello everybody,
I am trying to explore the Scanner class so I wrote a code that asks you to enter your name and birthday then returns them back to you:
---------------------------------------------

------------------------------------------
Now it compiles with error free but still bugs in the middle of the process as what next shows:

E:\Education\Coding\Java\Java WorkSpace>javac ScannerTest.java

E:\Education\Coding\Java\Java WorkSpace>java ScannerTest
Enter your name:
mm
Enter your Birthday in format(dd/mm/yy):
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at ScannerTest.main(ScannerTest.java:13)
------------------------------
Note: I am using notepad with windows terminal to compile and run my codes.

Thanks in advance.

 
Knute Snortum
Sheriff
Posts: 4274
127
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch, and thanks for using code tags!

You will run into problems if you close System.in. Keep the Scanner object open for all input.

Scanner.next() is also problematic. Use nextLine().

And then, when you use nextLine() and the next input is nextInt(), you will have another problem! nextLine() doesn't consume the CR at the end of the input, so you have to do that manually.

Implement all those changes and see how it works. Then post the new code here.
 
Campbell Ritchie
Marshal
Posts: 56525
172
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Knute Snortum wrote: . . . Scanner.next() is also problematic. . . .
I personally think nextLine can be worse, possibly because there are no good tutorials about it. Scanner#next() simply reads the next token as far as the next “delimiter”. If you hven't changed the “delimiter”, then think of next() as reading “one word”. You only get problems with nextLine if you call it after nextSomethingElse. Please tell us what your book says about nextLine, then see what Uncle Campbell has to say about it here. And compare that with the official documentation.

And welcome again
 
Badr Ibrahim
Greenhorn
Posts: 5
Eclipse IDE Redhat
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for your responses.
Knute Snortum wrote:And then, when you use nextLine() and the next input is nextInt(), you will have another problem! nextLine() doesn't consume the CR at the end of the input, so you have to do that manually.

I didn't use any nextInt() after nextLine() I just read the input into the Scanner object "sc0" then I used Delimiter so I can split the integers in the date(dd/mm/yy) so, I am not sure how should I make nextLine() before sc.nextInt().
Also, can you tell me what is CR consume means cause I searched and I am not sure I just found "Carriage Return".

Thanks.

 
Campbell Ritchie
Marshal
Posts: 56525
172
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
n old keyboards (40+ years ago) there used to be a key marked CR which means Campbell Ritchie Carriage Return which moved the print head to the left margin of the paper.
Please check carefully what the nextLine method does. It does tell you about line ends in the API documentation. As far as I can remember, it is only a problem if you call nextInt before nextLine. A CR character counts as whitespace so you can write… and get the same results from both the following inputs:When KS said that nextLine consumes the CR he meant that the line end characters at the end of the line are passed over. If you use ↩ to represent the line end, then you can start off writing
Mary had a little lamb*
*
… but withoiut the stars. If the line end is consumed the Scanner will start reading where the blue star is, not where the red star is.

Don't change delimiters on your Scanner. Use two Scanners.Note that the delimiter is a regular expression; please check in the Java™ Tutorials or another regular expressions tutorial that / is not a metacharacter.

You are better off however using an object which represents a date directly. Start reading in the Java™ Tutorials.
 
Campbell Ritchie
Marshal
Posts: 56525
172
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A few minutes ago, I wrote:. . . If you use ↩ to represent the line end, then you can start off writing
Mary had a little lamb*
*
. . .
Altered version in case anybody has difficulty distinguishing the colours:-
Mary had a little lamb*
*
… but without the stars. If the line end is consumed the Scanner will start reading where the black star is, not where the green star is.
 
Badr Ibrahim
Greenhorn
Posts: 5
Eclipse IDE Redhat
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for your support it's really helpful.
But, still I have to close some gaps I hope it doesn't bother you.

Now, I'll mention them as points:

1-I am using windows so end of line is set by using "CR + LF" characters which is ↩ so, are those characters also not consumable like the case with CR character?
2-How can I write this input ?
3-
Campbell Ritchie wrote:If the line end is consumed the Scanner will start reading where the blue star is, not where the red star is.
Mary had a little lamb*

Now, If the Scanner consumed the line end with represents 'Enter' it will ignore this character and continue reading from the red star?

Finally, I'd like to mention that I read about CR and LF maybe I couldn't get them correctly so please, if you found any conflicts I have, explain them to me.

Thanks again and again
 
Campbell Ritchie
Marshal
Posts: 56525
172
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Only use CR (= \r) or LF (= \n) if somebody has specifically told you so to do, and they want those characters rather than the usual line end combination. The JVM automatically alters the line end it is looking for depending on the operating system, so forget all about CR and LF. Read the documentation for Scanner#nextLine() and it tells you exactly where the cursor (i.e. where you are looking next) goes. It says nothing about CR or LF, but
line separator.
Look at the little stars after “Mary had a little lamb” and see where the Scanner moves to after nextLine. Yes, it goes to the red star. I used ↩ rather than CR or LF because I know you get different results from ↩ on different systems. Whatever you get from pushing the enter key is consumed whichever system you are using.
To write 123 456 789 use the space key and the enter key. Or the tab key. It doesn't matter; those all count as whitespace and that is part of the default delimiter for Scanner and you can see the effect of those inputs.
 
Badr Ibrahim
Greenhorn
Posts: 5
Eclipse IDE Redhat
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I know that nextLine() reads the rest of the line and stops when it finds the EOL whether it is CR or Enter characters.

1-If consuming Enter character makes the Scanner moves to the next line why consuming CR doesn't make the Scanner move to the line beginning as this is what CR do "Return of the Carriage"?!
2-
Knot Snortum wrote:And then, when you use nextLine() and the next input is nextInt(), you will have another problem! nextLine() doesn't consume the CR at the end of the input, so you have to do that manually.

I don't see what is the use of the 2nd line cause nextLine() means to ignore the current line, it'll be better if you provided me with a compiled code example if I am saying wrong.
3-Also, I tried to use "\r" but it functions like an Enter not like actual CR?

Thanks alot.
 
Knute Snortum
Sheriff
Posts: 4274
127
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's probably better to use next() rather than nextLine(). next() will consume whatever the <enter> key adds, I believe.
 
Campbell Ritchie
Marshal
Posts: 56525
172
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
'Fraid not. A call to next() skips any whitespace, then reads the next token and then stops before the next whitespace. Remember that all line terminator characters are whitespace.
A call to nextLine() returns everything between the current cursor position and the next line separator character, then moves to the beginning of the next line. It does not matter whether the line terminator characters are \r \n \r\n or any of the other line separators shown in the documentation for Pattern. The fact that \r is supposed to move the print head to the left does not affect the behaviour of the Scanner object. Try it by using ctrl‑M instead of the enter key.

Both next and nextLine have their uses, and you sometimes need one and sometimes the other.
 
Badr Ibrahim
Greenhorn
Posts: 5
Eclipse IDE Redhat
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Okay this is clarified.

Thanks a lot
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!