I'm doing a programming project and keep getting the error shown below.
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1585)
at ArrayPhoneDirectory.loadData(ArrayPhoneDirectory.java:42)
at ArrayPhoneDirectoryTester.main(ArrayPhoneDirectoryTester.java:18)
I thought this would be because the scanner read.nextLine() is going past the end of the text file. But I've used a while loop with hasNextLine so I'm not sure why this is happening.
Anyone know where I'm going wrong?
public void loadData (String sourceName){
Scanner read = new Scanner(sourceName);
while (read.hasNextLine()) {
String name = read.nextLine();
String telno = read.nextLine(); //ArrayPhoneDirectory Line 42
add(name, telno);
}
}
Associated text file
John
123
Bill
23
Hello
23455
Frank
12345
Dkddd
31231
You are reading two lines while only checking for the existence of one
Here is the second read
String telno = read.nextLine(); //ArrayPhoneDirectory Line 42
hasNextLine checks for only one line. You are trying to read two lines.
String name = read.nextLine();
String telno = read.nextLine();
which in case of odd number of lines can throw NoSuchElementException for second line you want to read.
hasNextLine()
will check only for one new line. you cannot read two lines after checking for just one.
If you have to continuously read records then you could do
public void loadData (String sourceName){
Scanner read = new Scanner(sourceName);
int i = 1;
while (read.hasNextLine()) {
if(i%2 != 0)
String name = read.nextLine();
else
String telno = read.nextLine(); //ArrayPhoneDirectory Line 42
add(name, telno);
i++;
}
}
Once you call nextLine the pointer gets incremented. Since, you have already called it before in this line:
String name = read.nextLine();
So, the next time you try to read it over here:
String telno = read.nextLine();
you get no such element exception. You should use this instead:
String telno = name
What you're doing is reading too many lines when checking for only one. It goes like this:
Problem
If the array on "lines" looks like this:
["This is line 1"]
Then read.hasNextLine() will return true. Then you enter your while loop. You run the first line which is:
String name = read.nextLine();
You retrieved one element from the above array, now it looks like this:
[]
Then you continue through your while loop:
String telno = read.nextLine();
Then the nextLine() method looks for a element in the array to give you, doesn't find any, and throws an exception.
Related
This code finds the first word "horror", but does not show me the whole line, only the word found.
File f = new File("MyFile.txt");
Scanner scan = new Scanner(f);
while (scan.hasNextLine()) {
String str = scan.next();
if (str.contains("horror")) {
System.out.println(str + " este horror");
}
}
Why is that?
The Scanner class has many methods for reading different types, and each has a corresponding hasNext...() method, for example nextInt() and hasNextInt(). You checked hasNextLine(), but used next() which returns the next word instead of nextLine() which returns the next line.
Change your code from:
String str = scan.next(); // read next word ❌
to:
String str = scan.nextLine(); // read next line ✅
Okay so I'm having a slight problem with scanner advancing an extra line. I have a file that has many lines containing integers each separated by one space. Somewhere in the file there is a line with no integers and just the word "done".
When done is found we exit the loop and print out the largest prime integer that is less than each given integer in each line(if integer is already prime do nothing to it). We do this all the way up until the line with "done".
My problem: lets say the file contains 6 lines and on the 6th line is the word done. My output would skip lines 1, 3 and 5. It would only return the correct values for line 2 and 4.
Here's a snippet of code where I read the values in:
Scanner in = new Scanner(
new InputStreamReader(socket.getInputStream()));
PrintStream out = new PrintStream(socket.getOutputStream());
while(in.nextLine() != "done"){
String[] arr = in.nextLine().split(" ");
Now I sense the problem is that the nextLine call in my loop advances the line and then the nextline.split call also advances the line. Thus, all odd number lines will be lost. Would there be another way to check for "done" without advancing a line or is there a possible command I could call to somehow reset the scanner back to the start of the loop?
The problem is you have 2 calls to nextLine() try something like this
String line = in.nextLine();
while (!"done".equals(line)) {
String[] arr = line.split(" ");
// Process the line
if (!in.hasNextLine()) {
// Error reached end of file without finding done
}
line = in.nextLine();
}
Also note I fixed the check for "done" you should be using equals().
I think you are looking for this
while(in.hasNextLine()){
String str = in.nextLine();
if(str.trim().equals("done"){
break;
}else{
String[] arr = str.split("\\s+");
//then do whatever you want to do
}
}
So, my end goal is to use an input file to instantiate an ArrayList of Letter objects. The file contains multiple cases of the following format:
from-to
line 1
...
line n
(*** is used as an indicator of a new letter. There are no blank lines between input lines, in other words, each line is followed immediately by a return and then the next line.)
Yet before I even attempt to instantiate multiple Letter objects, I am just trying to get the first one to work.
Scanner in = new Scanner(_file).useDelimiter("\\s+?|-");
ArrayList<Letter> letters = new ArrayList();
String from = in.next();
String to = in.next();
Letter temp = new Letter(from,to);
String s = in.next();
temp.addLine(s);
Where a Letter object takes two strings for the recipient and writer and can then have lines added to it. So my output should be:
Dear Recipient:
Line 1
...
Line n
Sincerely,
Writer
But when I use this my output is:
Dear Recipient:
Sincerely,
Writer
The documentation Scanner.nextLine() says this:
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.
So what the method actually does is give you whats left on that line only
So, you need to do this:
Scanner in = new Scanner(_file).useDelimiter("\\s+?|-");
ArrayList<Letter> letters = new ArrayList();
String from = in.next();
String to = in.next();
Letter temp = new Letter(from,to);
in.nextLine(); // <-- this is extra
// now we're ready to read the rest of the stuff
String s = in.nextLine();
temp.addLine(s);
I have the following code that reads through a line of students and the program should split at each white space then go to the next part of the text but I get arrayindexoutofBound exception.
The text file has several lines like this:
130002 Bob B2123 35 34 B2132 34 54 B2143 23 34
public static void main(String[] args) throws FileNotFoundException {
File f = new File("C:\\Users\\Softey\\Documents\\scores.txt");
Scanner sc = new Scanner(f);
List<MarkProcessing> people = new ArrayList<MarkProcessing>();
while(sc.hasNextLine()){
String line = sc.nextLine();
String[] details = line.split("\\s+");
String regNumber = details[0];
String name = details[1];
String modOne= details[2];
int courseM = Integer.parseInt(details[3]);
int examM = Integer.parseInt(details[4]);
String modTwo = details[5];
int courseM2 = Integer.parseInt(details[6]);
int examM2 = Integer.parseInt(details[7]);
String modThree = details[8];
int courseM3 = Integer.parseInt(details[9]);
int examM3= Integer.parseInt(details[10]);
MarkProcessing p = new MarkProcessing(regNumber, name, modOne,courseM, examM, modTwo,courseM2,examM2, modThree, courseM3, examM3);
people.add(p);
}
}
}
When it goes to details[1] I get the index error.
Without information regarding the input file, I am going to guess this is because of blank lines in your file. If this is the case, you should try something to ensure that you have enough pieces.. For this, your while loop could be something like this.
while(sc.hasNextLine()){
String line = sc.nextLine();
String[] details = line.split("\\s+");
if(details.length < 11) continue; // skip this iteration
...
}
Keep in mind this is only going to work if you are checking at least 11 items per line. If you need a more advanced method of parsing the input, whereas they may have any number of courses. You are better off thinking of another approach than simply storing values directly from indices.
You should try printing the line before parsing it so that you can see what causes it to blow up.
String line = sc.nextLine();
String[] details = line.split("\\s+");
String regNumber = details[0];
String name = details[1];
String modOne= details[2];
You are splitting on chunks of spaces. In the event you encounter a line with no spaces, then there will only be a single element and therefore details[1] will throw an IndexOutOfBoundsException.
My suggestion is to examine your input carefully. Does it have at trailing line feed? If so, that may be interpreted as a blank line
130002 Bob B2123 35 34 B2132 34 54 B2143 23 34
<blank line>
To split by space, you need to use:
String[] details = line.split(" "); // "\\s+" -> does not split by space.
In your case, it is trying to split the line by the regex pattern '//s+' and since this is not found, it considers the whole line to be one string. In this case, the size of the string array is 1. There is no details[1] and hence you get this error.
In this below program user enters the number of city name to be inserted and then a String array is initialized with that size.Then I try to iterate through loop and initialize every index of array with the value(City Name) inserted from user.
But when I tried to print value from array it ask for one less value..What I mean is if i say number of city is 2 ,so my loop should be iterated twice and twice I should insert value but instead i get to insert value only once.
On debugging i realized that the 0th element is getting inialized by itself from somewhere.I am not able to find the exact problem .
import java.util.Scanner;
public class EmptyStringGenerator {
public static void main(String []ard) {
Scanner scanner = new Scanner(System.in);
System.out.println("How many cities?");
String[]favoriteCities = new String[scanner.nextInt()];
for(int i=0;i<favoriteCities.length;i++){
favoriteCities[i]=scanner.nextLine();
}
for(String str:favoriteCities){
System.out.print(str+" ");
}
}
}
My Input:
2
Delhi
Output:
Delhi
The issue is that you read the int with nextInt(), but don't consume the line end! The rest of the line is left unprocessed, and the next nextLine() call goes on from that point.
nextLine() doc
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.
To correct the issue:
String[]favoriteCities = new String[scanner.nextInt()]; //read int
//consume line end, and do nothing with it
scanner.nextLine();
//now read the cities.
for(int i=0;i<favoriteCities.length;i++){
favoriteCities[i]=scanner.nextLine();
}
Recommended reading:
Scanner Java API doc
Line 0 is the end line after "2". nextInt() does not read that. Add a dummy nextLine() after reading the number.
Use next() method instead of nextLine().Since nextLine() reads the new line skipped by the nextInt() method .
nextLine()
Advances this scanner past the current line and returns the input that was skipped
next()
Finds and returns the next complete token from this scanner
So the code will be now
public static void main(String []ard)
{
Scanner scanner = new Scanner(System.in);
System.out.println("How many cities?");
String[]favoriteCities = new String[scanner.nextInt()];
for(int i=0;i<favoriteCities.length;i++)
{
favoriteCities[i]=scanner.next();
}
for(String str:favoriteCities)
{
System.out.print(str+" ");
}
}
If I understand the OP question correctly, input is int and city name, and the output should be number of times (int) the city name, say e.g 2 Delhi output Delhi Delhi, but he is getting only Delhi.
SOLUTION
String[]favoriteCities = new String[scanner.nextInt()];
String cityToBeAdded = scanner.next();
for(int i=0;i<favoriteCities.length;i++){
favoriteCities[i]=cityToBeAdded;
}
for(String str:favoriteCities){
System.out.print(str+" ");
}