Sign in to follow this  

Java Scanner class

This topic is 3937 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I begin with a String of integers, delimited by whitespaces. Ex: "1 2 3 6". I want to read in a String (such as in the example above) from the keyboard using a Scanner. The problem with Scanner objects is that they tokenize based on whitespaces, and so the String in the example will produce four integer tokens: (1), (2), (3) and (6). I want to then scroll through all the Scanner tokens and concatenate the string back together, as to make the final String read "1236". It is very important that I used this exact method. Here is my source code:
[source lang="java]
String input;
Scanner keyboard = new Scanner(System.in);
// User enters "1 2 3 6", let's just say.
while(keyboard.hasNext())
{
    input += keyboard.next();
    // Some other auxiliary code here.
}

System.out.println("This line never gets printed! Why!?!?");



What is happening is this: the Scanner reads "1 2 3 6" as input and correctly iterates through the Scanner's tokens (using the keyboard.hasNext() method in conjunction with the "while" statement). So if I try to print out the "input" String after every iteration I get output like this: 1 1 2 1 2 3 1 2 3 6 So I *know* keyboard.next() is successfully concatenating the String. However, after the last (4th) iteration, the while-loop haults the program, telling me that the hasNext() method isn't returning. I checked to make sure no "IteratorStateException"s are being thrown.... Why would hasNext() hault/block the program? Why does my System.out.println() command never execute??

Share this post


Link to post
Share on other sites
To quote the java Scanner documentation:
Quote:

A scanning operation may block waiting for input.

The next() and hasNext() methods and their primitive-type companion methods (such as nextInt() and hasNextInt()) first skip any input that matches the delimiter pattern, and then attempt to return the next token. Both hasNext and next methods may block waiting for further input. Whether a hasNext method blocks has no connection to whether or not its associated next method will block.

Share this post


Link to post
Share on other sites
What I think is happening is the system.in ALWAYS can receive new input, so having a while loop like that ios basically like saying, "I will wait for ever for an input, then when I get an input, I will do these tasks. I will then go back to step 1."

Share this post


Link to post
Share on other sites
You can include an exit value, say a newline character will exit the loop.

So something similar to this would solve the problem assuming you can include a newline character or another character to break out of the loop.
[source lang="java]
while(keyboard.hasNext())
{
char temp = keyboard.next();
if( temp == '\n') {
break;
}
input += temp;
// Some other auxiliary code here.
}




Edit: Just noticed next() returns a string. Replace char for String and use a string compare function in the if statement and it will work.

Share this post


Link to post
Share on other sites
Quote:
Original post by plywood
rip-off,

I noticed that in the API docs, but wasn't sure how to interpret that into writing different code. Any suggestions?


Well, you'll have to change the behaviour of the program. Under what circumstances do you wish to break the loop? At the moment it cannot end, the program you wrote waits for the keyboard input stream to end, for example using CTRL+C.

Quote:

I want to read in a String (such as in the example above) from the keyboard using a Scanner.

The problem with Scanner objects is that they tokenize based on whitespaces, and so the String in the example will produce four integer tokens: (1), (2), (3) and (6).

I want to then scroll through all the Scanner tokens and concatenate the string back together, as to make the final String read "1236".

It is very important that I used this exact method.


May I ask why? I dont see how the scanner class can be programmed around, unless you wait for the user to type a specific string or something...

Share this post


Link to post
Share on other sites
rip-off,

I am simply most comfortable with the Scanner class.

What other classes could I use, that read input from the keyboard, that in your opinion would work better? If the Scanner class cannot be programmed around, there must be a more elegant solution.

How would I code differently using this other input reader?

And to answer your question, I simply want the reader/tokenizer to stop when it has parsed a total of four integers (negative or positive), such as in my first example: "1 2 3 6" or in any other example, say "2 -45 31 0".

Share this post


Link to post
Share on other sites
"It is very important that I used this exact method"

sounds like a case of homework-itis

"I am simply most comfortable with the Scanner class"

completely contradicting your previous statement

Share this post


Link to post
Share on other sites
Quote:
Original post by plywood
rip-off,

I am simply most comfortable with the Scanner class.

What other classes could I use, that read input from the keyboard, that in your opinion would work better? If the Scanner class cannot be programmed around, there must be a more elegant solution.

How would I code differently using this other input reader?

And to answer your question, I simply want the reader/tokenizer to stop when it has parsed a total of four integers (negative or positive), such as in my first example: "1 2 3 6" or in any other example, say "2 -45 31 0".


Your looping condition is incorrect then. The end of the loop isn't tied to the end of the input stream.

You should instead have an array or container object which you add ints to as you scan them and terminate the loop when the number of integers scanned is more than 4.

Share this post


Link to post
Share on other sites
Yeah, well, "plywood" is a dumb name, too. For that matter, so is "Zahlman". It's the internet; get used to it :)

Anyway. The idea conceptually is that a Scanner reads all the tokens that its source is capable of producting. There's nothing that prevents System.in from producing more tokens (the user could type more), so the program will just wait that way.

You should be careful about your expectations from the user, though.

When you say you are looking for "four tokens", where does the number four come from? You aren't going to "see" any tokens until the user hits the enter key - what if the user puts five tokens on the first line of input? Do you want to just ignore the last one, or report an error?

Probably the best way to deal with the fact that user input comes in a line at a time, is to read a line at a time into some buffer, and then inspect the buffer contents. In C++, we do that with the std::string and std::stringstream classes. In Java, we can .readLine() from the input using an appropriate Reader subclass (sorry I don't remember the details), and then replace the Scanner with a StringTokenizer (which cuts up a String into tokens in the same way).

Share this post


Link to post
Share on other sites
Quote:
Original post by theStormWeaver
I have a suggestion that could solve your java problems...

stop programming in java.


Hilarious I'm sure.

Quote:

In Java, we can .readLine() from the input using an appropriate Reader subclass (sorry I don't remember the details), and then replace the Scanner with a StringTokenizer (which cuts up a String into tokens in the same way).


BufferedReader I think?

(checks...)

BufferedReader reader = new BufferedReader( new InputStreamReader( System.in ));

String line = reader.readLine();

Share this post


Link to post
Share on other sites

This topic is 3937 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this