Reputation: 3
I've been trying to practice I/O file programming and I'm still at the basics. Writing into a file using the java was simple enough but reading to a file is beginning to give me a headache. Here's a simple program I tried to run(btw, I based the program from a book by Liang) .
import java.util.Scanner;
import java.io.File;
public class Reading {
private static Scanner n;
public static void main(String[] args) throws Exception
{
File files = new File("samples.txt");
n = new Scanner(files);
while(n.hasNext())
{
String firstName = n.next();
String mi = n.next();
String lastName = n.next();
int score = n.nextInt();
System.out.println(
firstName + " " + mi + " " + lastName + " " + score);
}
n.close();
}
}
Here's the error:
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 OOPFinals.Reading.main(Reading.java:17)
How do I make this program work? Help!
Upvotes: 0
Views: 3329
Reputation: 180
Your code is working given that the right input file "samples.txt" is provided. For example, given the following input:
Richard Phillips Feynman 100
Paul Adrien Dirac 90
Everything works fine, however if you use the following:
Richard Feynman 100
Paul Adrien Dirac 90
then you obtain the NoSuchElementException. In the last example, I removed the middle name that your program is expecting. As such, we can conclude that you are expecting to read information in a file with no information left to read. I recommend something like the following:
import java.util.Scanner;
import java.util.StringTokenizer;
import java.io.File;
public class Reading {
private static Scanner n;
public static void main(String[] args) throws Exception
{
File files = new File("samples.txt");
n = new Scanner(files);
String data;
while(n.hasNextLine() && !(data = n.nextLine()).equals(""))
{
StringTokenizer st = new StringTokenizer(data);
if(st.countTokens() >= 4) {
String firstName = (String) st.nextElement();
String mi = (String) st.nextElement();
String lastName = (String) st.nextElement();
int score = Integer.parseInt( (String) st.nextElement());
System.out.println(
firstName + " " + mi + " " + lastName + " " + score);
} else {
System.err.println("This line is malformed!");
}
}
n.close();
}
}
In this program, you can have a sample file that has empty lines and it expects to read 4 tokens per line or else it prints an error message informing you that a line has malformed input.
Upvotes: 0
Reputation: 2565
What is happening in your code, you are trying to read from the Scanner although there's nothing left there to read. What you should do - You need to check n.hasNext() before each call to n.next() or n.nextInt(), or just read the entire line (which seems exactly what you want):
while (n.hasNextLine()) {
String line = n.nextLine();
System.out.println(line);
}
Upvotes: 2
Reputation: 1425
Sometimes when you're reading a file you'll run into various characters. Some are letters, some are numbers, and some are integers. You need to check whether it's a letter, number, or an integer because the following line assumes you are passing an integer:
int score = n.nextInt();
It can be resolved by checking for integers:
int score = 0;
if(n.hasNextInt()) { score = n.nextInt(); }
When you're reading from the program, make sure to take Cathial's answer into consideration. By using hasNext()
, you're only checking if there is one string, also known as a token. You should check if there are n
strings available where n
is the number of .next()
functions in your loop.
Upvotes: 0
Reputation: 328
The NoSuchElementException
is thrown by Scanner.next()
and means there are no more tokens to be found in the file.
The problem here is that your while()
loop only guarantees that there is at least ONE token left to read from the file, however on each iteration of the loop you are reading in FIVE tokens.
Upvotes: 2