0

入力ファイルにエラーがある場合、スキャナが失敗した入力ファイルの行を見つけることは可能ですか?

次のコードは、エラーが発生した行番号ではなく、リーダーの合計行を常に出力します。

import java.io.LineNumberReader;
import java.io.StringReader;
import java.util.NoSuchElementException;
import java.util.Scanner;
import org.junit.Test;

public class ScannerTests {

    static private final String text = "FUNCTION_BLOCK Unnamed_project\n\tVAR_INPUT\n\t\tUnnamed_variable1::REAL;\n\tEND_VAR\nEND_FUNCTION_BLOCK";

    @Test
    public void scannerLineNumberFailedTest() {

        LineNumberReader reader = new LineNumberReader(new StringReader(text));

        int lineNumber = -1;

        try {
            Scanner sc = new Scanner(reader);
            sc.useDelimiter("\\s*\\b\\s*");

            sc.next("(?i)FUNCTION_BLOCK");
            String blockName = sc.next();
            assert sc.hasNext("(?i)VAR_INPUT");
            sc.next("(?i)VAR_INPUT"); 
            String variableName = sc.next();
            sc.next(":");                       // line of failure - got a unexpected '::'
            String type = sc.next("\\w+"); 
            sc.next(";");
            sc.next("(?i)END_VAR");             
            sc.next("(?i)END_FUNCTION_BLOCK");

            assert "Unnamed_project".equals(blockName);
            assert "Unnamed_variable1".equals(variableName);
            assert "REAL".equals(type);

            sc.close();
        } catch (NoSuchElementException ex) {

            lineNumber = reader.getLineNumber() + 1;
            System.err.println("Error in line: " + lineNumber);
        }

        assert lineNumber == 3; 
    }
}
4

1 に答える 1

3

AScannerは、行番号または文字番号を追跡しません。

行数と文字数を数えるカスタムを使用してこれを実装しようとすることもできますがFilterReader、すべての場合で正確であるとは限りません。スキャナがストリームをどれだけ通過したかがわかりますが、スキャナがメソッド内の多数の文字を先読みし、hasNext巻き戻して別の nextメソッドを使用して入力を読み取ることができるという事実を考慮することはできません。例えば:

if (sc.hasNext("[A-Z ]+")) {
   sc.nextInteger();

メソッドの呼び出しが失敗した場合nextInteger()、 によって報告される「現在の位置」は、不正な整数が検出されたストリーム位置を何文字もFilterReader過ぎている可能性があります。

最悪の場合、この巻き戻しにより、区切り文字の構成方法によっては、行の境界を越えて戻る可能性があります。したがって、(理論的には) 行番号でさえ確実に追跡することはできません。


すべてのケースで行番号と文字番号を 100% 正確に追跡する唯一の方法は、入力ストリーム カーソルの前後の動きのすべてを通じて、これらを追跡する独自の入力解析システムを実装することです。

于 2013-06-23T13:20:54.510 に答える