如何将扫描仪转换为字符串或列表

How to convert scanner to String or 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"));

但是,它在稍后解析扫描仪上的数字时给我带来了问题。我试过调试它,但我似乎无法理解问题所在。例如,我让它在解析之前将字符串打印到控制台。它会打印一个正确的数字(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 值可以在 -2,147,483,648 到 2,147,483,647 之间。

fullInput.get(1) 给你 010101110111 大于 2,147,483,647.

你可以用long。

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。这足以导致 Long.parseLong(...) 抛出 NumberFormatException。 (parseXxx 方法不允许在参数中出现多余的字符,例如空格。)

一个可能解决无关空白问题的方法是 trim 字符串;例如

  System.out.println(Long.parseLong(fullInput.get(1).trim()));

trim() 方法 (javadoc) returns 删除任何前导 and/or 尾随空格的字符串。

但是还有另一种方法可以解决这个问题。如果您不关心输入文件中的每个数字是否在单独的一行上,您可以这样做:

  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 类型。