java 使用 Scanner 的 nextLine() 和 hasNextLine() 方法的问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3652586/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 02:51:58  来源:igfitidea点击:

Problem using the nextLine() and hasNextLine() methods of Scanner

javajava.util.scanner

提问by Harish

I have a log file containing the following data:

我有一个包含以下数据的日志文件:

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

最短路径(2)::RV3280-RV0973C-RV2888C
最短路径(1)::RV3280-RV2502C
最短路径(2)::RV3280-RV2501C-RV1263
最短路径(2)::RV2363-Rv3285-RV3280

From each line, i require the number within the brackets, name of the first protein (RV3280 in the first line) and the name of the last protein (RV2888C in the first line).

在每一行中,我需要括号内的数字、第一个蛋白质的名称(第一行中的 RV3280)和最后一个蛋白质的名称(第一行中的 RV2888C)。

I have written a code for this using the Scannerobject.

我已经使用Scanner对象为此编写了代码。

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 i 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 correct it?

为什么会出现此错误,如何纠正?

采纳答案by Key

Your input data probably doesn't end with a line separator which would cause this. Calls to findInLinemoves the Scanner past the matching pattern and if you are at the end of the input data when calling nextLineit will throw the NoSuchElementException

您的输入数据可能不会以行分隔符结尾,这会导致这种情况。调用findInLine将 Scanner 移过匹配模式,如果您在调用nextLine它时处于输入数据的末尾,则会抛出NoSuchElementException

A easy fix without re-arranging the code to much would be to end the while loop with:

一个简单的解决方法是在不重新安排代码的情况下结束 while 循环:

if (s.hasNextLine()) {
    s.nextLine();
}

回答by atamanroman

    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 weird characters or empty lines in your file?

这对我很有效,也许您的文件中有一些奇怪的字符或空行?

2 empty lines at the end give me that: Exception in thread "main" java.lang.IllegalStateException: No match result available

最后的 2 个空行给了我:线程“main”中的异常 java.lang.IllegalStateException: No match result available

If your input file is that strictly formatted, you can do something like that, which is way easier because you can get rid of that nasty regex ;)

如果您的输入文件格式严格,您可以做类似的事情,这更容易,因为您可以摆脱那些讨厌的正则表达式;)

    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]);

        }
    }