java.util.NoSuchElementException: No line found when line exists in file - java

I have a Code where I am scanning the lines using Scanner Class and looping till there are no lines left.
My code looks like this:
File file = new File(filePath);
if (file.exists()) {
Scanner s = new Scanner(file);
String tmp = null;
int result = 0;
try {
while (true) {
tmp = s.nextLine();
if (tmp != null && tmp.equals("")) {
result += Integer.parseInt(tmp);
}
System.out.println(runSequence(Integer.parseInt(tokens[0])));
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(result);
}
It gives the error at
tmp = s.nextLine();
java.util.NoSuchElementException: No line found
Which is odd because earlier the same code was working fine.
Why is this line giving an error?
Edit:
My mistake i did not state the question correctly, i particularly left the try catch block out of the while loop so that i could make an exit when the lines ended...My question is why am i not able to read any of the lines...i have about 3-4 lines to read in the txt file and it is not reading any and giving exception at the first line read itself...

I think the better way to code is to have a condition in your while loop using Scanner#hasNextLine(). Scanner#hasNextLine() would make sure that code inside while would only run if it has a line in the file=.
while (s.hasNextLine()) {
tmp = s.nextLine();
if (tmp != null && tmp.equals("")) {
result += Integer.parseInt(tmp);
}

if (tmp != null && tmp.equals(""))
should be (if you are trying to check given string is not empty string)
if (tmp != null && !tmp.isEmpty())
I think you reach at the end of file where there is no remaining line and your condition is while(true) so it tries to read that time also . So you getting NoSuchElementException(if no line was found )
So better to change your while loop as
while (s.hasNextLine()){
tmp = s.nextLine();
// then do something
}

while (s.hasNextLine())
{
//...
}

Related

Java ArrayList missing first value

I am taking data from a text file and putting it into an ArrayList. However the first line of the text file is not being printed out.
public static void secondMain() {
BufferedReader reader;
var lines = new ArrayList<String>();
var rooms = new ArrayList<Room>();
try {
reader = new BufferedReader(new FileReader("rooms.txt"));
String line = reader.readLine();
while (line != null) {
line = reader.readLine();
lines.add(line);
}
reader.close();
for (int i = 0; i < lines.size() - 1; i++) {
String[] words = lines.get(i).split(" ");
var room = new Room();
room.RoomNumber = Integer.parseInt(words[0]);
room.Type = (words[1]);
room.Price = Double.parseDouble(words[2]);
room.Bool1 = Boolean.parseBoolean(words[3]);
room.Bool2 = Boolean.parseBoolean(words[4]);
room.Availability = (words[5]);
rooms.add(room);
}
for(int i = 0; i < rooms.size(); i++) {
System.out.println(rooms.get(i).RoomNumber);
System.out.println(rooms.get(i).Type);
System.out.println(rooms.get(i).Price);
System.out.println(rooms.get(i).Bool1);
System.out.println(rooms.get(i).Bool2);
System.out.println(rooms.get(i).Availability);
}
Apologies for the Image, it was the only way i could figure out how to show the formatting of the text file.
The current output is displaying room number 102 as the first room which obviously isn't correct.
If anyone could also help me figure out how to format my console output the same way as the text file that'd also be great. currently it is displaying each individual string/int etc. on a different line.
Thanks.
If you need any more information please just ask!
This has nothing to do with the ArrayList. You can reproduce the problem by replacing the lines.add(line) call with System.out.println(line) and you'll see that the first line is missing from the output. Look at your first call to readLine(), before the while loop. You test that the value is non-null... and that's all you do with it (comments mine):
String line = reader.readLine(); // Read the value...
while (line != null) { // Test for it being non-null
line = reader.readLine(); // Then ignore the value you've just tested,
// by reading the next line.
lines.add(line);
}
You then call readLine() again. Note that your list will always end with a null value (unless it's the first line read) because your loop effectively says "while the last entry I added to the list isn't null". The simplest fix is to swap the order of the statements within your loop:
String line = reader.readLine();
while (line != null) {
lines.add(line);
line = reader.readLine();
}
Now you're adding a line immediately after checking whether it's non-null, before reading the next line.
The problem is here:
String line = reader.readLine(); // you read the first line
while (line != null) {
line = reader.readLine(); // read second line
lines.add(line); // add second line
}
You read the first line, check if it's not null, and then read the second line right away, before you add it to the list. All you need to do is switch the order.
String line = reader.readLine();
while (line != null) {
lines.add(line);
line = reader.readLine();
}

How to read specific lines with bufferedReader

I need to find some specific data from txt file, see code bellow.
while ((line = bufferedReader.readLine())!= null) {
//pokial obsahuje string zapíš do array
if (line.toLowerCase().contains("list c.")) {
parsedData.add(line);
}
if(line.toLowerCase().startsWith("re")) {
parsedData.add(line);//add found data to array
//i need to access and save second and third line after this one
}
System.out.println(line);
}
In the second condition, when I find a line that starts with "re" I need to save the second and third line after this specific one.
from your question i am not sure but if your target is to get next couple of lines (for example 2) after receiving re at start of line, you can do it by having some flags.
boolean needsToConsider = false;
int countOfLines = 2;
while ((line = bufferedReader.readLine())!= null) {
if(needsToConsider && countOfLines > 0){
// add here
countOfLines--;
if(countOfLines == 0)
needsToConsider = false;
}
//pokial obsahuje string zapíš do array
if (line.toLowerCase().contains("list c.")) {
parsedData.add(line);
}
if(line.toLowerCase().startsWith("re")) {
parsedData.add(line);//add found data to array
//i need to access and save second and third line after this one
needsToConsider = true;
}
A simple approach here might be to just use a counter to keep track of hitting those second and third lines:
int counter = 0;
while ((line = bufferedReader.readLine())!= null) {
if (line.toLowerCase().contains("list c.")) {
parsedData.add(line);
}
else if (line.toLowerCase().startsWith("re")) {
parsedData.add(line);
counter = 2;
}
else if (counter > 0) {
// add second and third lines after "re" here
parsedData.add(line);
--counter;
}
}
A more advanced approach could be to read in the entire portion of text of interest, and then use a regex matcher to extract what you want.

Ignoring blank lines in CSV file in Java

I am trying to iterate through a CSV file in Java. It iterates through the entire file, but will get to the end of the file and try to read the next blank line and throw an error. My code is below.
public class Loop() {
public static void main(String[] args) {
BufferedReader br = null;
String line = "";
try {
HashMap<Integer, Integer> changeData = new HashMap<Integer, Integer>();
br = new BufferedReader(new FileReader("C:\\xxxxx\\xxxxx\\xxxxx\\the_file.csv"));
String headerLine = br.readLine();
while ((line = br.readLine()) != null) {
String[] data = line.split(",");
/*Below is my latest attempt at fixing this,*/
/*but I've tried other things too.*/
if (data[0].equals("")) { break; }
System.out.println(data[0] + " - " + data[6]);
int changeId = Integer.parseInt(data[0]);
int changeCv = Integer.parseInt(data[6]);
changeData.put(changeId, changeCv);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Like I typed, this works fine until it gets to the end of the file. When it gets to the end of the file, I get the error Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0 at com.ucg.layout.ShelfTableUpdates.main(ShelfTableUpdates.java:23). I've stepped through the code by debugging it in Spring Tool Suite. The error comes up whenever I try to reference data[0] or data[6]; likely because there is nothing in that line. Which leads me back to my original question of why it is even trying to read the line in the first place.
It was my understanding that while ((line = br.readLine()) != null) would detect the end of the file, but it doesn't seem to be. I've tried re-opening the file and deleting all of the blank rows, but that did not work.
Any idea how I can detect the end of the file so I don't get an error in this code?
ANSWER:
Credit goes to user #quemeraisc. I also was able to replace the commas with blanks, and if the line then equals null or "", then you know that it is the end of the file; in my case, there are no blank rows before the end of the file. This still does not solve the problem of detecting the end of the file in that if I did have blank rows in between my data that were not the EOF then this would detect those.
Solution 1:
if (data.length < 7) {
System.out.println(data.length);
break;
}
Solution 1:
if (line.replace(",", "").equals(null) || line.replace(",", "").equals("")) {
System.out.println(line.replace(",", ""));
break;
}
Just skip all blank lines:
while ((line = br.readLine()) != null) {
if( line.trim().isEmpty() ) {
continue;
}
....
....
The last line may contain some control characters (like new line, carriage return, EOF and others unvisible chars), in this case a simple String#trim() doesn't remove them, see this answer to know how to remove them: How can i remove all control characters from a java string?
public String readLine() will read a line from your file, even empty lines. Thus, when you split your line, as in String[] data = line.split(","); you get an array of size 1.
Why not try :
if (data.length >= 7)
{
System.out.println(data[0] + " - " + data[6]);
int changeId = Integer.parseInt(data[0]);
int changeCv = Integer.parseInt(data[6]);
changeData.put(changeId, changeCv);
}
which will make sure there are at least 7 elements in your array before proceeding.
To skip blank lines you could try:
while ((line = reader.readLine()) != null) {
if(line.length() > 0) {
String[] data = line.split(",");
/*Below is my latest attempt at fixing this,*/
/*but I've tried other things too.*/
if (data[0] == null || data[0].equals("")) { break; }
System.out.println(data[0] + " - " + data[6]);
int changeId = Integer.parseInt(data[0]);
int changeCv = Integer.parseInt(data[6]);
changeData.put(changeId, changeCv);
}
}
Instead of replace method use replaceAll method. Then it will work.

reading data from file and breaking it into tokens

I am using the following code after reading from a text file as to break the input of the text file into tokens:
String input;
while(true)
{
input = bin.readLine();
if (input == null)
{
System.out.println( "No data found in the file");
return 0;
}
break;
}
StringTokenizer tokenizer = new StringTokenizer(input);
Then:
for (int i=0; i < numAtt; i++)
{
attributeN[i] = tokenizer.nextToken();
}
I cannot understand why the attributeNames gets the tokens in the first line of the text file only, doesn't while(true) keep on reading the whole file? Also is there a way to avoid the while(true) and using break to terminate it?
Your break after if (input == null) { } is breaking the while, so your code only read one line.
Also is there a way to avoid the while(true) and using break to
terminate it?
Do it in this way:
while ((input = bin.readLine()) != null) {
//split input line here
}
Also, consider using String#split() to split the line in tokens. Example for the separator , :
String attributeNames[] = input.split(",");
The best way is using:
String splittedString[] = input.split("the separator");
It's recommended by Oracle.
Are you just trying to get tokens from the first line? If so, you don't need the while loop at all. Just remove the while { from the beginning and break; } from the end.

How do I make my java code search only for a to z and 0 to 9

My java code takes almost 10-15minutes to run (Input file is 7200+ lines long list of query). How do I make it run in short time to get same results?
How do I make my code to search only for aA to zZ and 0 to 9??
If I don't do #2, some characters in my output are shown as "?". How do I solve this issue?
// no parameters are used in the main method
public static void main(String[] args) {
// assumes a text file named test.txt in a folder under the C:\file\test.txt
Scanner s = null;
BufferedWriter out = null;
try {
// create a scanner to read from the text file test.txt
FileInputStream fstream = new FileInputStream("C:\\user\\query.txt");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
// Write to the file
out = new BufferedWriter(new FileWriter("C:\\user\\outputquery.txt"));
// keep getting the next String from the text, separated by white space
// and print each token in a line in the output file
//while (s.hasNext()) {
// String token = s.next();
// System.out.println(token);
// out.write(token + "\r\n");
//}
String strLine="";
String str="";
while ((strLine = br.readLine()) != null) {
str+=strLine;
}
String st=str.replaceAll(" ", "");
char[]third =st.toCharArray();
System.out.println("Character Total");
for(int counter =0;counter<third.length;counter++){
//String ch= "a";
char ch= third[counter];
int count=0;
for ( int i=0; i<third.length; i++){
// if (ch=="a")
if (ch==third[i])
count++;
}
boolean flag=false;
for(int j=counter-1;j>=0;j--){
//if(ch=="b")
if(ch==third[j])
flag=true;
}
if(!flag){
System.out.println(ch+" "+count);
out.write(ch+" "+count);
}
}
// close the output file
out.close();
} catch (IOException e) {
// print any error messages
System.out.println(e.getMessage());
}
// optional to close the scanner here, the close can occur at the end of the code
finally {
if (s != null) {
// close the input file
s.close();
}
}
}
For something like this I would NOT recommend java though it entirely possible it is much easier with GAWK or something similar. GAWK also has java like syntax so its easy to pick up. You should check it out.
SO isn't really the place to ask such a broad how-do-I-do-this-question but I will refer you to the following page on regular expression and text match in Java. Also, check out the Javadocs for regexes.
If you follow that link you should get what you want, else you could post a more specific question back on SO.

Categories