The problem of using the nextLine () and hasNextLine () methods of the scanner

I have a log file containing the following data:

The shortest path (2) :: RV3280-RV0973C-RV2888C
The shortest path (1) :: RV3280-RV2502C
The shortest path (2) :: RV3280-RV2501C-RV1263
Shortest path (2) :: RV2363-Rv3285-RV3280

Each line requires a number in brackets, the name of the first protein (RV3280 in the first line) and the name of the last protein (RV2888C in the first line).

I wrote the code for this using the Scanner object.

 try{ Scanner s = new Scanner(new File(args[0])); while (s.hasNextLine()) { s.findInLine("Shortest path\\((\\d+)\\)::(\\w+).*-(\\w+)"); // at each line, look for this pattern MatchResult result = s.match(); // results from for (int i=1; i<=result.groupCount(); i++) { System.out.println(result.group(i)); } s.nextLine(); // line no. 29 } s.close(); } catch (FileNotFoundException e) { System.out.print("cannot find file"); } 

I get the desired results, but also get an error message. The output I get for the above input file is:

 Exception in thread "main" java.util.NoSuchElementException: No line found at java.util.Scanner.nextLine(Scanner.java:1516) at nearnessindex.Main.main(Main.java:29) 2 RV3280 RV2888C 1 RV3280 RV2502C 2 RV3280 RV1263 2 RV2363 RV3280 Java Result: 1 BUILD SUCCESSFUL (total time: 1 second) 

Why does this error occur and how can I fix it?

+7
java java.util.scanner
source share
2 answers

Your input probably does not end with a line separator that can cause this. The calls to findInLine move the scanner beyond the corresponding template, and if you are at the end of the input when calling nextLine , it will throw a NoSuchElementException

An easy fix without re-compiling the code would be to end the while loop:

 if (s.hasNextLine()) { s.nextLine(); } 
+3
source share
  public static void main(String[] args) { Scanner s = new Scanner("Shortest path(2)::RV3280-RV0973C-RV2888C" + "\nShortest path(1)::RV3280-RV2502C" + "\nShortest path(2)::RV3280-RV2501C-RV1263" + "\nShortest path(2)::RV2363-Rv3285-RV3280"); while (s.hasNextLine()) { s.findInLine("Shortest path\\((\\d+)\\)::(\\w+).*-(\\w+)"); // at each line, look for this pattern MatchResult result = s.match(); // results from for (int i = 1; i <= result.groupCount(); i++) { System.out.println(result.group(i)); } s.nextLine(); // line no. 29 } s.close(); } } run: 2 RV3280 RV2888C 1 RV3280 RV2502C 2 RV3280 RV1263 2 RV2363 RV3280 BUILD SUCCESSFUL (total time: 0 seconds) 

This works well for me, maybe you have some strange characters or blank lines in the file?

2 blank lines at the end give me the following: An exception in the stream "main" java.lang.IllegalStateException: Available match result

If your input file is strictly formatted, you can do something like this, which is much simpler because you can get rid of this nasty regular expression;)

  String[] lines = new String[]{"Shortest path(2)::RV3280-RV0973C-RV2888C", "Shortest path(1)::RV3280-RV2502C", "Shortest path(2)::RV3280-RV2501C-RV1263", "Shortest path(2)::RV2363-Rv3285-RV3280", "\n", "\n"}; final int positionOfIndex = 14; final int startPositionOfProteins = 18; for (String line : lines) { if (!line.trim().isEmpty()) { System.out.print(line.charAt(positionOfIndex) + ": "); String[] proteins = line.substring(startPositionOfProteins).split("-"); System.out.println(proteins[0] + " " + proteins[proteins.size() -1]); } } 
0
source share

All Articles