> Please consider below section of code . It works as written; > however if bold line is omitted
> source ("in" is a scanner object) input is ignored and "enter the > file name where the result is written"
> is displayed on console and the code runs just fine.
> What is going on here?
> Tnx.
> Richard
Hi Richard,
I fleshed out your code enough so that it compiled, and then ran it in BlueJ 3.0.7. I did not see the problem you describe - I need only to request the nextLine() once before it returns the line that was entered.
Given that the code doesn't compile by itself, there is clearly some surrounding code that you didn't include. Perhaps there's an issue in that other code?
> System.out.println("enter the source document file name"); > *source = in.nextLine();// need to request 2x times to work--bug??* > source = in.nextLine();
Davin already replied about this specific code segment, suggesting that the problem was perhaps due to surrounding (but omitted) code.
Let me venture a guess that you've done other operations with the scanner before this code segment, and that the scanner is not "looking" where you think it is. For example, consider this short transcript on the console, with program-generated lines preceded by a << and human-typed input lines tagged with >>, and assuming all lines end in the platform's line terminator sequence:
<< Enter a word: >> hello << 5 << enter the source document file name >> myfile.txt
Now, suppose that the code to work with this looks like this:
System.out.println("Enter a word:"); String word = in.next(); int wordLength = word.length(); System.out.println(wordLength); System.out.println("enter the source document file name"); source = in.nextLine();// need to request 2x times to work--bug??
What actually happens? First, the program prints out "Enter a word:". Then the program calls in.next() which is going to block waiting for input--waiting for the person to type something.
Then the person types "hello\n" (I'll just use \n to represent the enter key, which will be translated to the host platform's line terminator sequence). Console input in Java is line-buffered by default, so no matter how many words the person types, the enter key must be pressed as well before any of the characters get passed on to the scanner and processed.
After the person types enter/return, the entire line, including the line termination character, is available for the scanner to process. But what does the call to in.next() actually do? First it skips over any whitespace (the default delimiter for scanners) to the first non-whitespace character it can find-- here, the "h". Then it continues scanning over non-whitespace characters until it finds another delimiter--here, the newline (or the first character of the line termination sequence, to be platform independent). Then it stops and returns the word it found: "hello".
String word = in.next(); // returns "hello"
BUT ... where is the scanner looking after next() returns? The scanner stops at the end of the word it returns--right after that "o", but right before the line termination sequence. If you call next() again, t will skip over any whitespace (including line terminators) looking for the next word, so that probably isn't an issue.
BUT ... the next scanner action is to call nextLine(). What does nextLine() do? It starts with the very first character the scanner is looking at, and scans up to and including the very first line termination sequence it finds. It grabs all the text before the line termination sequence, skips over the line termination sequence, and leaves the scanner looking at the very next character following that line termination sequence.
In this hypothetical example, the scanner was looking just after the "o" in hello, right *at* the line terminator on the end of the first line typed by the person at the console. So it merrily does exactly what I described-- and returns an empty string, the sequence of characters it saw just before the first line terminator it found. It also leaves the scanner looking at the beginning of the second line the person typed, so the second call does as expected.
In summary, I don't have any idea what your surrounding code looks like, but I agree with Davin that the problem lies there, and the behavior you are seeing is likely due to mistaken assumptions about where the scanner is actually looking (that is, it is still looking earlier in the input sequence than you think, due to calls to scanner methods like next() that are not line-oriented).
Hope that helps ...
-- Steve
--------------------------------------------------------------------------- Virginia Tech, CS Dept. Web-CAT: Web-based Center for Software Testing 114 McBryde Hall (0106) Automatic grading using student-written tests Blacksburg, VA 24061 USA http://web-cat.org/ (540)-231-5723 http://people.cs.vt.edu/~edwards/
Davin, Thank you for taking a look at this for me. Here is the code which runs; however, if I comment out one of the scanner calls it fails. Richard I am using BJ version 3.0.7(Java version 1.7.0)
----- Original Message ----- From: Davin McCall To: bluej-discuss@googlegroups.com Sent: Thursday, March 29, 2012 12:07 PM Subject: Re: [BlueJ Discuss] scanner String console input question
On 28/03/12 22:35, Richard Thomas wrote: Please consider below section of code . It works as written; however if bold line is omitted
source ("in" is a scanner object) input is ignored and "enter the file name where the result is written"
is displayed on console and the code runs just fine.
What is going on here?
Tnx.
Richard
Hi Richard,
I fleshed out your code enough so that it compiled, and then ran it in BlueJ 3.0.7. I did not see the problem you describe - I need only to request the nextLine() once before it returns the line that was entered.
Given that the code doesn't compile by itself, there is clearly some surrounding code that you didn't include. Perhaps there's an issue in that other code?
Davin
-- You received this message because you are subscribed to the Google Groups "BlueJ Discuss" group. To post to this group, send email to bluej-discuss@googlegroups.com. To unsubscribe from this group, send email to bluej-discuss+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/bluej-discuss?hl=en.
I think this is what must be happening. Please see the code previously sent to Davin. What is the right code structure for this sort of scanner input sequence?
----- Original Message ----- From: "Stephen Edwards" <edwa...@cs.vt.edu> To: <bluej-discuss@googlegroups.com> Sent: Thursday, March 29, 2012 2:31 PM Subject: Re: [BlueJ Discuss] scanner String console input question
> On 3/28/12 5:35 PM, Richard Thomas wrote: >> System.out.println("enter the source document file name"); >> *source = in.nextLine();// need to request 2x times to work--bug??* >> source = in.nextLine();
> Davin already replied about this specific code segment, suggesting > that the problem was perhaps due to surrounding (but omitted) code.
> Let me venture a guess that you've done other operations with the > scanner before this code segment, and that the scanner is not > "looking" where you think it is. For example, consider this short > transcript on the console, with program-generated lines preceded > by a << and human-typed input lines tagged with >>, and assuming > all lines end in the platform's line terminator sequence:
> << Enter a word: > >> hello > << 5 > << enter the source document file name > >> myfile.txt
> Now, suppose that the code to work with this looks like this:
> System.out.println("Enter a word:"); > String word = in.next(); > int wordLength = word.length(); > System.out.println(wordLength); > System.out.println("enter the source document file name"); > source = in.nextLine();// need to request 2x times to work--bug??
> What actually happens? First, the program prints out "Enter a word:". > Then the program calls in.next() which is going to block waiting for > input--waiting for the person to type something.
> Then the person types "hello\n" (I'll just use \n to represent the > enter key, which will be translated to the host platform's line > terminator sequence). Console input in Java is line-buffered by > default, so no matter how many words the person types, the enter > key must be pressed as well before any of the characters get > passed on to the scanner and processed.
> After the person types enter/return, the entire line, including > the line termination character, is available for the scanner to > process. But what does the call to in.next() actually do? > First it skips over any whitespace (the default delimiter for > scanners) to the first non-whitespace character it can find-- > here, the "h". Then it continues scanning over non-whitespace > characters until it finds another delimiter--here, the newline > (or the first character of the line termination sequence, to > be platform independent). Then it stops and returns the word > it found: "hello".
> String word = in.next(); // returns "hello"
> BUT ... where is the scanner looking after next() returns? > The scanner stops at the end of the word it returns--right > after that "o", but right before the line termination sequence. > If you call next() again, t will skip over any whitespace > (including line terminators) looking for the next word, so > that probably isn't an issue.
> BUT ... the next scanner action is to call nextLine(). What > does nextLine() do? It starts with the very first character > the scanner is looking at, and scans up to and including the > very first line termination sequence it finds. It grabs > all the text before the line termination sequence, skips > over the line termination sequence, and leaves the scanner > looking at the very next character following that line > termination sequence.
> In this hypothetical example, the scanner was looking just > after the "o" in hello, right *at* the line terminator on > the end of the first line typed by the person at the > console. So it merrily does exactly what I described-- > and returns an empty string, the sequence of characters > it saw just before the first line terminator it found. > It also leaves the scanner looking at the beginning of > the second line the person typed, so the second call does > as expected.
> In summary, I don't have any idea what your surrounding > code looks like, but I agree with Davin that the problem > lies there, and the behavior you are seeing is likely due to > mistaken assumptions about where the scanner is actually > looking (that is, it is still looking earlier in the > input sequence than you think, due to calls to scanner > methods like next() that are not line-oriented).
> Hope that helps ...
> -- Steve
> --------------------------------------------------------------------------- > Virginia Tech, CS Dept. Web-CAT: Web-based Center for Software Testing > 114 McBryde Hall (0106) Automatic grading using student-written tests > Blacksburg, VA 24061 USA http://web-cat.org/ > (540)-231-5723 http://people.cs.vt.edu/~edwards/
> -- > You received this message because you are subscribed to the Google Groups > "BlueJ Discuss" group. > To post to this group, send email to bluej-discuss@googlegroups.com. > To unsubscribe from this group, send email to > bluej-discuss+unsubscribe@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/bluej-discuss?hl=en.
> Davin, > Thank you for taking a look at this for me. > Here is the code which runs; however, if I comment out one of the > scanner calls it fails. > Richard > I am using BJ version 3.0.7(Java version 1.7.0)
From looking at the code, the problem is as Steve Edwards described:
24 System.out.println("enter the word length (an interger from 1 to 10"); 25 wordLength = in.nextInt(); 26 System.out.println(wordLength); 27 System.out.println("enter the source document file name"); 28 source = in.nextLine();// need to request 2x times to work--bug?? 29 source = in.nextLine();
You use (line 25) 'nextInt' to read an integer, but this processes only the part of the line buffer which the integer spans - leaving any following whitespace (probably none), and the line terminator character(s). The first call to nextLine() (line 28) processes the rest of the buffer, immediately seeing the line terminator and therefore returning an empty line (consuming the line terminator in the process). The second nextLine() call (line 29) then processes the next line that is entered.
To illustrate the problem another way, try running your program, and when prompted for the seed length, enter the following all one one line:
10 20 abc.txt
You'll notice the following 'nextInt' call doesn't wait for more input, since it just continues processing the line buffer (and gets the 20). The following call to nextLine would read the ' abc.txt' part of the line (you could print out the return value to verify this).
----- Original Message ----- From: Davin McCall To: bluej-discuss@googlegroups.com Sent: Thursday, March 29, 2012 4:04 PM Subject: Re: [BlueJ Discuss] scanner String console input question
On 29/03/12 21:46, Richard Thomas wrote: Davin, Thank you for taking a look at this for me. Here is the code which runs; however, if I comment out one of the scanner calls it fails. Richard I am using BJ version 3.0.7(Java version 1.7.0)
From looking at the code, the problem is as Steve Edwards described:
24 System.out.println("enter the word length (an interger from 1 to 10"); 25 wordLength = in.nextInt(); 26 System.out.println(wordLength); 27 System.out.println("enter the source document file name"); 28 source = in.nextLine();// need to request 2x times to work--bug?? 29 source = in.nextLine();
You use (line 25) 'nextInt' to read an integer, but this processes only the part of the line buffer which the integer spans - leaving any following whitespace (probably none), and the line terminator character(s). The first call to nextLine() (line 28) processes the rest of the buffer, immediately seeing the line terminator and therefore returning an empty line (consuming the line terminator in the process). The second nextLine() call (line 29) then processes the next line that is entered.
To illustrate the problem another way, try running your program, and when prompted for the seed length, enter the following all one one line:
10 20 abc.txt
You'll notice the following 'nextInt' call doesn't wait for more input, since it just continues processing the line buffer (and gets the 20). The following call to nextLine would read the ' abc.txt' part of the line (you could print out the return value to verify this).
Davin
-- You received this message because you are subscribed to the Google Groups "BlueJ Discuss" group. To post to this group, send email to bluej-discuss@googlegroups.com. To unsubscribe from this group, send email to bluej-discuss+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/bluej-discuss?hl=en.
> I think this is what must be happening. Please see the code previously sent to Davin. > What is the right code structure for this sort of scanner input sequence?
Assuming you want to enforce line-by-line input, you should use nextLine() to get a full line and parse the returned String using other methods (such as Integer.parseInt(...)).
Eg
String intLine = in.nextLine(); int value = Integer.parseInt(intLine);
> Assuming you want to enforce line-by-line input, you should use
> nextLine() to get a full line and parse the returned String
This is a good idea. Note that it is really easy to create a new Scanner for a string, so you can still use the scanner's features (instead of going to parseInt() and the like) if you prefer. Just one one scanner connected to your input channel to read input line by line, and create a second scanner for each line you wish to "carve up" individually.
-- Steve
--------------------------------------------------------------------------- Virginia Tech, CS Dept. Web-CAT: Web-based Center for Software Testing 114 McBryde Hall (0106) Automatic grading using student-written tests Blacksburg, VA 24061 USA http://web-cat.org/ (540)-231-5723 http://people.cs.vt.edu/~edwards/