I've been having some trouble getting the Scanner class to operate the
way I'd like. I'm doing some fairly basic file IO and I can't seem to
get the class to load the last line/token any way I try.
First, I tried using the following:
File InFile=new File("input.txt");
Scanner In=new Scanner(InFile);
String Ln;
for ( Ln=In.nextLine() ; In.hasNextLine() ; Ln=In.nextLine() ) {
// Do stuff with Ln in here.
}
Unfortunately, this moves the "cursor" in the file down one line, and
returns the text skipped - probably not what I was trying to do. Also,
when it gets to the end of the file, hasNextLine() returns false (as
it should) and the loop finishes. Unfortunately, it's still left
precious information in the file!
When I tell it to load the final line using nextLine(), it tries
advancing past the end of the file and gives me a
NoSuchElementException.
So, I tried changing it up to be the following:
File InFile=new File("input.txt");
Scanner In=new Scanner(InFile).useDelimiter("\n");
String Ln;
for ( Ln=In.next() ; In.hasNext() ; Ln=In.next() ) {
// Do stuff with Ln in here.
}
This, however, according to the method description, only returns those
tokens which both start AND end with the delimiter - making it
impossible for me to use it to load the last token in the file, simply
because there's no newlines after it.
How can I get that last line (preferably, using the Scanner class)? Is
it possible to specify that the EOF sequence is a delimiter - or would
that even work?
Thanks in advance for any help,
DemonWasp 7 25311
DemonWasp wrote:
....
First, I tried using the following:
File InFile=new File("input.txt");
Scanner In=new Scanner(InFile);
String Ln;
for ( Ln=In.nextLine() ; In.hasNextLine() ; Ln=In.nextLine() ) {
// Do stuff with Ln in here.
}
Unfortunately, this moves the "cursor" in the file down one line, and
returns the text skipped - probably not what I was trying to do. Also,
when it gets to the end of the file, hasNextLine() returns false (as
it should) and the loop finishes. Unfortunately, it's still left
precious information in the file!
When I tell it to load the final line using nextLine(), it tries
advancing past the end of the file and gives me a
NoSuchElementException.
...
From the API docs
<http://java.sun.com/j2se/1.5.0/docs/api/java/util/Scanner.html>:
Scanner.hasNextLine()
"Returns true if there is another line in the input of this scanner. ... The
scanner does not advance past any input."
Scanner.nextLine()
"Advances this scanner past the current line and returns the input that was
skipped. This method returns the rest of the current line, excluding any line
separator at the end. The position is set to the beginning of the next line."
In other words, nextLine() is supposed to return the text that was skipped.
If your input has only one line (or zero), the loop will not execute. The
initialization will read the one line, then the condition will fail because
there is no second line.
When the loop finished and you tried to call nextLine() again (assuming you
used the same Scanner instance), it threw the exception because hasNextLine()
had already failed. Calling nextLine() when ! hasNextLine() raises the exception.
Try something like:
Scanner in = new Scanner( inFile );
while ( in.hasNextLine() )
{
String line = in.nextLine();
// do something with line
}
(The convention is to name variables with a lower-case first letter.)
- Lew
On Sun, 24 Sep 2006 17:25:34 -0400, Lew <co****@comcast.netwrote:
<snip>
>Scanner.hasNextLine() "Returns true if there is another line in the input of this scanner. ... The scanner does not advance past any input."
Scanner.nextLine() "Advances this scanner past the current line and returns the input that was skipped. This method returns the rest of the current line, excluding any line separator at the end. The position is set to the beginning of the next line."
In other words, nextLine() is supposed to return the text that was skipped.
I recognise this, but I probably didn't make it sufficiently clear in
my post. However, this wasn't the main issue.
>If your input has only one line (or zero), the loop will not execute. The initialization will read the one line, then the condition will fail because there is no second line.
When the loop finished and you tried to call nextLine() again (assuming you used the same Scanner instance), it threw the exception because hasNextLine() had already failed. Calling nextLine() when ! hasNextLine() raises the exception.
Try something like:
Scanner in = new Scanner( inFile ); while ( in.hasNextLine() ) {
String line = in.nextLine();
// do something with line }
(The convention is to name variables with a lower-case first letter.)
Yeah, but I'm unconventional :P. Again though, this example misses the
point of the question that I was asking.
What I *was* asking was "how do I get the last line from a file, even
when there is no trailing whitespace?"
Thanks anyway,
DemonWasp
DemonWasp wrote:
On Sun, 24 Sep 2006 17:25:34 -0400, Lew <co****@comcast.netwrote:
<snip>
>Scanner.hasNextLine() "Returns true if there is another line in the input of this scanner. ... The scanner does not advance past any input."
Scanner.nextLine() "Advances this scanner past the current line and returns the input that was skipped. This method returns the rest of the current line, excluding any line separator at the end. The position is set to the beginning of the next line."
In other words, nextLine() is supposed to return the text that was skipped.
I recognise this, but I probably didn't make it sufficiently clear in
my post. However, this wasn't the main issue.
>If your input has only one line (or zero), the loop will not execute. The initialization will read the one line, then the condition will fail because there is no second line.
When the loop finished and you tried to call nextLine() again (assuming you used the same Scanner instance), it threw the exception because hasNextLine() had already failed. Calling nextLine() when ! hasNextLine() raises the exception.
Try something like:
Scanner in = new Scanner( inFile ); while ( in.hasNextLine() ) { String line = in.nextLine(); // do something with line }
(The convention is to name variables with a lower-case first letter.)
Yeah, but I'm unconventional :P. Again though, this example misses the
point of the question that I was asking.
What I *was* asking was "how do I get the last line from a file, even
when there is no trailing whitespace?"
Thanks anyway,
DemonWasp
I don't confuse being unconventional with being dense. He just showed
you what you need to do. Personally, I would point you to read the
Scanner api. Learn how to Google the groups also.
--
Thanks in Advance...
IchBin, Pocono Lake, Pa, USA http://weconsultants.phpnet.us
__________________________________________________ ________________________
'If there is one, Knowledge is the "Fountain of Youth"'
-William E. Taylor, Regular Guy (1952-)
"DemonWasp" <jd****@msn.comwrote in message
news:r5********************************@4ax.com...
I've been having some trouble getting the Scanner class to operate the
way I'd like. I'm doing some fairly basic file IO and I can't seem to
get the class to load the last line/token any way I try.
First, I tried using the following:
File InFile=new File("input.txt");
Scanner In=new Scanner(InFile);
String Ln;
for ( Ln=In.nextLine() ; In.hasNextLine() ; Ln=In.nextLine() ) {
// Do stuff with Ln in here.
}
Unfortunately, this moves the "cursor" in the file down one line, and
returns the text skipped - probably not what I was trying to do. Also,
when it gets to the end of the file, hasNextLine() returns false (as
it should) and the loop finishes. Unfortunately, it's still left
precious information in the file!
When I tell it to load the final line using nextLine(), it tries
advancing past the end of the file and gives me a
NoSuchElementException.
In your "Do stuff with Ln in here" section, doesn't it process the last
line right before exiting the loop?
>
So, I tried changing it up to be the following:
File InFile=new File("input.txt");
Scanner In=new Scanner(InFile).useDelimiter("\n");
Don't bother with "useDelimiter". I think that'll be a dead end for you.
- Oliver
DemonWasp <jd****@msn.comwrote:
>What I *was* asking was "how do I get the last line from a file, even when there is no trailing whitespace?"
I can't repro the problem - help me understand what I'm missing. I'm using
the following test class:
import java.io.*;
import java.util.Scanner;
public class ScannerTest {
public static void main(String[] args) throws Exception {
if (args == null || args.length != 1) {
System.out.println("Specify filename.");
System.exit(1);
}
File input = new File(args[0]);
InputStream is = new FileInputStream(input);
int lineNum=0;
for (Scanner s = new Scanner(is); s.hasNextLine();) {
String line = s.nextLine();
System.out.println(lineNum++ + " " + line);
}
}
}
And input file with no trailing newline created by:
$ cat testfile
lineone
linetwo^d^d
The following happens:
$ java -cp . ScannerTest
0 lineone
1 linetwo
This is what I'd expect. What's it do for you?
--
Mark Rafn da***@dagon.net <http://www.dagon.net/>
On Mon, 25 Sep 2006 10:03:55 -0700, da***@dagon.net (Mark Rafn) wrote:
>DemonWasp <jd****@msn.comwrote:
>>What I *was* asking was "how do I get the last line from a file, even when there is no trailing whitespace?"
I can't repro the problem - help me understand what I'm missing. I'm using the following test class:
import java.io.*; import java.util.Scanner; public class ScannerTest {
public static void main(String[] args) throws Exception {
if (args == null || args.length != 1) {
System.out.println("Specify filename.");
System.exit(1);
}
File input = new File(args[0]);
InputStream is = new FileInputStream(input);
int lineNum=0;
for (Scanner s = new Scanner(is); s.hasNextLine();) {
String line = s.nextLine();
System.out.println(lineNum++ + " " + line);
}
} }
And input file with no trailing newline created by: $ cat testfile lineone linetwo^d^d
The following happens:
$ java -cp . ScannerTest 0 lineone 1 linetwo
This is what I'd expect. What's it do for you?
You're not missing anything, your code is subtly different. I figured
out the problem.
In my code, I had:
for ( String ln=in.nextLine() ; in.hasNextLine() ; ln=in.nextLine() )
which works fantastically until it gets to the last line in the file.
The "increment" part of the for loop (ie. ln=in.nextLine()) goes and
gets the last line. Then the second part of the for loop checks
(in.hasNextLine()) and returns false - then it skips the body of the
loop.
This caused the following problems:
1) I missed the last line of input because the loop exited too early.
2) When I tried adding an ln=in.nextLine() statement after the for
loop, to gather the "missing" last line, I triggered a
NoSuchElementException because, clearly, I had already loaded the last
line in the file.
The solution is to make sure that the test is done BEFORE I read in
the next line. So the following code works perfectly:
while(in.hasNextLine()){
ln=in.nextLine()
}
Thanks to everyone for the help.
/DemonWasp
DemonWasp <jd****@msn.comwrote:
>I've been having some trouble getting the Scanner class to operate the way I'd like.
Came back to read the OP to see what I'd missed. You misstate the problem.
It's not the Scanner doing the wrong thing, you're confused about how a for()
loop works.
>for ( Ln=In.nextLine() ; In.hasNextLine() ; Ln=In.nextLine() ) {
// Do stuff with Ln in here. }
Remember,
for( a; b; c) { d }
is exactly translatable as
{ a; while (b) { d; c; }
I'm unwilling to put up with stupidly nonstandard naming, so I'll just pretend
your variables are lowercase. Your code is identical to:
ln=in.nextLine();
while (in.hasNextLine) {
// do stuff
ln = in.nextLine();
}
This is just wrong. You're getting line 0, then test for line n+1 before
processing line n and getting n+1. You'll blow up with empty input, and skip
processing the last line. You'll GET the last line, as the last part of
processing the previous, but your loop condition is now false, so you won't
process it.
>Unfortunately, this moves the "cursor" in the file down one line, and returns the text skipped - probably not what I was trying to do. Also, when it gets to the end of the file, hasNextLine() returns false (as it should) and the loop finishes. Unfortunately, it's still left precious information in the file!
Nope, it left the information in your ln variable.
>When I tell it to load the final line using nextLine(), it tries advancing past the end of the file and gives me a NoSuchElementException.
As it should. You already read the last line, you just haven't processed it
yet.
>How can I get that last line (preferably, using the Scanner class)? Is it possible to specify that the EOF sequence is a delimiter - or would that even work?
You _ARE_ getting the last line. you're just discarding it by getting it at
the end of your loop rather than the beginning. try the following:
in = new Scanner(input);
while (in.hasNextLine) {
ln = in.nextLine();
// do stuff
}
or (if you want your locals to conveniently go out of scope after the loop
for (in = new Scanner(input); in.hasNextLine; ) {
String ln = in.nextLine;
// do stuff
}
--
Mark Rafn da***@dagon.net <http://www.dagon.net/> This discussion thread is closed Replies have been disabled for this discussion. Similar topics
15 posts
views
Thread by Ridimz |
last post: by
|
4 posts
views
Thread by Charles Erwin |
last post: by
|
16 posts
views
Thread by DJP |
last post: by
|
2 posts
views
Thread by Eric Lilja |
last post: by
|
35 posts
views
Thread by RyanS09 |
last post: by
|
6 posts
views
Thread by magix |
last post: by
|
3 posts
views
Thread by CCLeasing |
last post: by
| | | | | | | | | | | | |