Read multiple integers in multiple lines

I am currently writing a dissertation for a bachelor's degree in graph theory and use a java scanner to convert a txt file with edges into my graph in a Java class. My txt file looks like this:

1 2 72 3
2 3 15 98
4 7 66 49
5 6 39 48
6 9 87 97
8 13 31 5

The results are sorted as: initial peak, drain peak, cost, capacity.

My code is as follows:

Graph graph = new Graph(false); File f = new File("Filepath"); Scanner in = new Scanner(f); while (in.hasNextLine()) { for (int i =1; i<= numberEdges; i++) { String s = in.nextLine(); try (Scanner inscan = new Scanner(s)) { while (inscan.hasNext()) { int source = inscan.nextInt(); int sink = inscan.nextInt(); double cost =inscan.nextDouble(); double capacity = inscan.nextDouble(); Vertex Source = new Vertex(source); Vertex Sink = new Vertex(sink); Edge edge = new Edge(Source,Sink, cost, capacity); graph.addEdge(edge); } } } } in.close(); 

I tried to scan each string into a String and then scan the String into my variables. It always throws a “NoLineFound” exception in the first line of the for loop, and if I try it with line output, I don't get any. But when I turn off the second scanner and try again, I get all the lines in the output, but at the end the exception is “NoLineFound”.

I checked my txt file and the last line does not have the end of the UTF8 line, but I do not know how to do this.

+6
source share
4 answers

I think your problem comes from this:

 while (in.hasNextLine()){ for (int i =1; i<= numberEdges; i++) { 

Firstly, the iteration is redundant ( while or for are unitary enough to read each line. You need to make a choice between them). In addition, if your file has less lines than numberEdges , a java.util.NoSuchElementException will be raised.

If the number of lines in the file is constant, use for :

 for (int i =1; i<= numberEdges; i++) 

remove the attached while (in.hasNextLine()) . This is not required. Iteration control is already done with for .

If the number of lines in the file may differ, use only while :

  while (in.hasNextLine()){ 

But in any case, do not use both.

+6
source

With Java 8 threads:

 Files .lines(f.toPath()) .map(l ->Arrays.stream(l.split(" ")).mapToDouble(Double::parseDouble).toArray()) .map(a->new Edge(new Vertex((int)a[0]), new Vertex((int)a[1]), a[2], a[3])) .forEach(graph::addEdge); 
+6
source

You read nextLine() in a loop after one check for hasNextLine() . You need to check after each read to avoid the “NoLineFound” exception.

It seems like a nested loop is completely unnecessary. You can read the file in turn, ignoring empty lines and plot your schedule without first knowing the number of edges that it has:

 Graph graph = new Graph(false); File f = new File("Filepath"); Scanner in = new Scanner(f); while (in.hasNextLine()) { String s = in.nextLine(); try (Scanner inscan = new Scanner(s)) { if (!inscan.hasNext()) { continue; // Ignore empty lines } int source = inscan.nextInt(); int sink = inscan.nextInt(); double cost =inscan.nextDouble(); double capacity = inscan.nextDouble(); Vertex Source = new Vertex(source); Vertex Sink = new Vertex(sink); Edge edge = new Edge(Source,Sink, cost, capacity); graph.addEdge(edge); } } in.close(); 
+2
source

Just do a post-read check to avoid the "NoLineFound" exception.

You can use the code below to scan a file:

 import java.io.File; import java.util.Scanner; public class ReadFile { public static void main(String[] args) { try { System.out.print("Enter the file name with extension : "); Scanner input = new Scanner(System.in); File file = new File(input.nextLine()); input = new Scanner(file); while (input.hasNextLine()) { String line = input.nextLine(); System.out.println(line); } input.close(); } catch (Exception ex) { ex.printStackTrace(); } } } 
+1
source

Source: https://habr.com/ru/post/1013634/


All Articles