【问题标题】:How to convert scanner to String or List如何将扫描仪转换为字符串或列表
【发布时间】:2022-01-20 09:21:38
【问题描述】:

我有一个带有多行文本(代表数字)的扫描仪,我想将扫描仪中的所有文本转换为列表。 示例:

Scanner myScanner = new Scanner(new File("input.txt"));

输入.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());

你知道第一种方法有什么问题吗?或者有更好的方法吗?

【问题讨论】:

  • 由于您没有显示字符串,也没有显示它们必须如何拆分,因此这个问题可能仍然难以回答。请始终从我们的角度看待您的问题和问题,这些人只知道您展示和告诉我们的内容。
  • 最终结果是 fullInput 将是扫描仪读取的所有行的列表?在这种情况下,将 sc.hasNext() 更改为 sc.hasNextLine() 并将 sc.next() 更改为 sc.nextLine()。
  • 如果您的目标是简单地将文件的所有行读取为String[],请使用Files.readAllLines。然后,您可以使用Arrays.asList 将其包装为List
  • 当您尝试将行解析为数字时,我感觉真正的 问题正在发生。这可能是由于数字字符串上的前导/尾随空格之类的。尝试使用Integer.parseInt(someString.trim())
  • @StephenC 你是对的。我添加了 .trim() 函数,它现在可以完美运行。但是,File.readAllLines() 方法似乎不存在

标签: java list java.util.scanner


【解决方案1】:

因为您正在解析一个字符串,该字符串表示一个超出整数大小的数字。

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);

【讨论】:

    【解决方案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 方法不允许在参数中使用多余的字符,例如空格。)

    多余空格问题的一个可能解决方案是修剪字符串;例如

      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 提出了一个有效的观点。 看起来这些是二进制数。如果它们实际上是二进制的,那么使用 Long.parseLong(string, radix) 解析它们更有意义,radix 值为 2。但是,如果您使用 parseLong 将它们解析为十进制(正如您目前正在做的那样)您的值问题适合long类型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多