是否有方法获取java.util.Scanner失败的输入文件的行号(和列号)?
当输入文件中出现错误时,是否可以找出扫描仪在输入文件的哪一行出现故障 以下代码始终打印出读卡器中的总行数,而不是发生错误的行号:是否有方法获取java.util.Scanner失败的输入文件的行号(和列号)?,java,input,Java,Input,当输入文件中出现错误时,是否可以找出扫描仪在输入文件的哪一行出现故障 以下代码始终打印出读卡器中的总行数,而不是发生错误的行号: import java.io.LineNumberReader; import java.io.StringReader; import java.util.NoSuchElementException; import java.util.Scanner; import org.junit.Test; public class ScannerTests {
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;
}
}
扫描仪不跟踪行号或字符号
您可以尝试使用一个自定义的FilterReader
来实现这一点,它可以计算行数和字符数,但我认为这并非在所有情况下都是准确的。它将告诉您扫描仪通过流的距离,但它不能考虑扫描仪可以在hasNext
方法中提前读取大量字符,然后使用不同的next
方法返回并读取输入。例如:
if (sc.hasNext("[A-Z ]+")) {
sc.nextInteger();
如果nextInteger()
方法调用失败,则FilterReader
报告的“当前位置”可能超过检测到错误整数的流位置许多字符
在最坏的情况下,这种回绕可以带你回到线的边界。。。取决于分隔符的配置方式。因此(理论上)即使是行号也无法确定地跟踪
在所有情况下,要100%准确地跟踪行数和字符数,唯一的方法是实现自己的输入解析系统,该系统本身就可以跟踪这些内容。。。通过输入流光标的所有前后移动。AScanner
不跟踪行号或字符号
您可以尝试使用一个自定义的FilterReader
来实现这一点,它可以计算行数和字符数,但我认为这并非在所有情况下都是准确的。它将告诉您扫描仪通过流的距离,但它不能考虑扫描仪可以在hasNext
方法中提前读取大量字符,然后使用不同的next
方法返回并读取输入。例如:
if (sc.hasNext("[A-Z ]+")) {
sc.nextInteger();
如果nextInteger()
方法调用失败,则FilterReader
报告的“当前位置”可能超过检测到错误整数的流位置许多字符
在最坏的情况下,这种回绕可以带你回到线的边界。。。取决于分隔符的配置方式。因此(理论上)即使是行号也无法确定地跟踪
在所有情况下,要100%准确地跟踪行数和字符数,唯一的方法是实现自己的输入解析系统,该系统本身就可以跟踪这些内容。。。通过输入流光标的所有前后移动。谢谢你的回答,但它没有回答这个问题。@Tuto-事实上,它回答了。只是,这不是你想听的答案。扩展的答案是我可以接受的答案。可能还不足以在扫描器周围编写包装器,最好使用解析器生成器来实现这一点。@Tuto您可以使用ANTLR为您的扫描器生成一个lexer和/或解析器language@Don-为什么您建议使用ANTLR而不是其中一种替代方案?你为什么认为他不知道ANTLR?谢谢你的回答,但这并没有回答这个问题。@Tuto-事实上,它回答了。只是,这不是你想听的答案。扩展的答案是我可以接受的答案。可能还不足以在扫描器周围编写包装器,最好使用解析器生成器来实现这一点。@Tuto您可以使用ANTLR为您的扫描器生成一个lexer和/或解析器language@Don-为什么您建议使用ANTLR而不是其中一种替代方案?为什么你认为他不知道ANTLR?看起来你正试图用扫描仪解析编程语言(或DSL)的文本。这不是一个好主意,您应该使用像ANTLR这样的解析器生成器。看起来您正试图使用扫描仪来解析编程语言(或DSL)的文本。这不是一个好主意,您应该使用像ANTLR这样的解析器生成器。