Java Scanner class

Started by
11 comments, last by rip-off 17 years, 1 month ago
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??
Advertisement
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.
rip-off,

I noticed that in the API docs, but wasn't sure how to interpret that into writing different code. Any suggestions?
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."
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.
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...
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".
"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
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.
rip-off, thank you for your help I now have my program working!
Glak, dumb name.

This topic is closed to new replies.

Advertisement