当输入文件中有错误时,是否可以找出扫描仪在输入文件的哪一行失败?
下面的代码总是打印出读取器中的总行数,而不是发生错误的行号:
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;
}
}
最佳答案
Scanner
不跟踪行号或字符号。
您可以尝试使用计数行和字符的自定义FilterReader
来实现此目的,但是我认为这并非在所有情况下都是准确的。它会告诉您扫描仪从流中走了多远,但是它无法考虑到扫描仪可以使用hasNext
方法预先读取多个字符,然后回退并使用不同的next
方法。例如:
if (sc.hasNext("[A-Z ]+")) {
sc.nextInteger();
如果
nextInteger()
方法调用失败,则FilterReader
报告的“当前位置”可能比检测到错误整数的流位置之后的字符更多。在最坏的情况下,这种回退可以使您回到线边界之外……这取决于您如何配置定界符。因此(理论上)甚至无法确定行号。
在所有情况下均能100%准确地跟踪行号和字符数的唯一方法是实现自己的输入解析系统,该系统本身会通过输入流游标的所有向前和向后移动来跟踪这些内容。
关于java - 有没有办法获取java.util.Scanner失败的输入文件的行号(和列号)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17261116/