我有一个扫描仪,里面有很多行文本(表示数字(,我想将扫描仪中的所有文本转换为List。示例:
Scanner myScanner = new Scanner(new File("input.txt"));
input.txt:
000110100110
010101110111
111100101011
101101001101
011011111110
011100011001
110010011100
000001011100
101110100110
010001011100
011111001010
100111100101
111111000010
我的第一个想法是通过将分隔符更改为我知道不在文件中的东西来将其转换为字符串:
myScanner.useDelimiter("impossible String");
String content = myScanner.next();
然后使用
List<String> fullInput = Arrays.asList(content.split("n"));
然而,这给我以后在扫描仪上解析数字带来了问题。我试过调试它,但似乎无法理解这个问题。例如,我让它在解析之前将String打印到控制台。它会打印一个正确的数字(asString(,然后在应该解析时给我NumberFormatException。
这是可运行的代码:
public static void main(String[] args) throws FileNotFoundException {
Scanner myScanner = new Scanner(new File("input.txt"));
myScanner.useDelimiter("impossible String");
String content = myScanner.next();
List<String> fullInput = Arrays.asList(content.split("n"));
System.out.println(fullInput.get(1));
System.out.println(Long.parseLong(fullInput.get(1)));
}
这是我在第一次失败后最终使用的:
Scanner myScanner = new Scanner(new File("input.txt"));
List<String> fullInput = new ArrayList<>();
while (sc.hasNextLine())
fullInput.add(myScanner.nextLine());
你知道第一种方法有什么问题吗?或者有更好的方法吗?
因为您正在解析一个表示超过整数大小的数字的字符串。
int
的值可以介于-2147483648到2147483647之间。
fullInput.get(1)
给出的010101110111
大于2,147,483,647
。
你可以使用长。
long val = Long.parseLong(fullInput.get(1));
如果字符串表示二进制数,并且您希望将其转换为int,那么在解析字符串时需要提供基数。
int val = Integer.parseInt(fullInput.get(1), 2);
对于您在这里尝试做的事情,Scanner
是错误的解决方案。
如果您的目标是简单地将文件的所有行读取为String[]
,那么您可以使用Files.readAllLines(Path, Charset)
方法(javadoc(来执行此操作。然后可以使用Arrays.asList(...)
将其包装为List
。
您实际所做的在某些情况下可能有效。但一个可能的问题是,String.split("n")
仅适用于线路终止符为单个NL
字符的系统。在Windows上,行终止符是CR
NL
序列。在这种情况下,String.split("n")
将在除最后一个字符串/行之外的所有字符串/行的末尾留下一个CR
。这将足以导致CCD_ 16抛出CCD_。(parseXxx
方法不允许参数中出现诸如空白之类的无关字符。(
对于无关的空白问题,一个可能的解决方案是修剪字符串;例如
System.out.println(Long.parseLong(fullInput.get(1).trim()));
trim()
方法(javadoc(返回一个字符串,其中删除了任何前导和/或尾部空白。
但还有另一种方法可以解决这个问题。如果你不在乎输入文件中的每个数字是否在一个单独的行上,你可以这样做:
Scanner myScanner = new Scanner(new File("input.txt"));
List<Long> numbers = new ArrayList<>();
while (myScanner.hasNextLong()) {
numbers.append(myScanner.nextLong());
}
最后,@ChengThao提出了一个有效的观点。看起来就像这些是二进制数字。如果它们实际上是二进制的,那么使用radix
值为2的Long.parseLong(string, radix)
来解析它们更有意义。但是,如果您使用parseLong
将它们解析为十进制(正如您当前所做的那样(,则问题中的值将适合long
类型。