【问题标题】:scanner.useDelimiter("\n\n") in javaJava 中的scanner.useDelimiter("\n\n")
【发布时间】:2015-09-28 05:45:01
【问题描述】:

我有一个简单的代码来理解它读取文件 (input2.txt) 并显示它。

import java.util.*;
import java.io.*;

public class Test {

  public static void main(String[] args )  throws Exception {
    Scanner scanner = new Scanner(new File(args[0]) );
    scanner.useDelimiter("\n\n");   
    String[] grid = scanner.next().split("\n");
    scanner.close();

    for(int row = 0; row < grid.length; row++) {
        for(int col = 0; col < grid[row].length(); col++) {
            System.out.print(grid[row].charAt(col) + " ");
        }
        System.out.println();
    }
  } 
}
  1. input.txt

  1. java测试input.txt

我不明白的是

scanner.useDelimiter("\n\n");

为什么它使用两个"\n\n" 而不是一个"\n"? 仅供参考,如果我使用scanner.useDelimiter("\n"); 它不能正常工作。这只是从文件中读取第一行。

【问题讨论】:

    标签: java split delimiter


    【解决方案1】:

    您的文件包含换行符 (\n),因此将分隔符设置为单个换行符将导致 next() 返回第一行。

    由于您的文件不包含任何空行,即没有双换行符,next() 将返回第一个标记,即整个文件内容。

    为什么有人选择\n\n?谁知道呢。

    另外请注意,这在 Windows 上不起作用,其中行由 \r\n 分隔。

    【讨论】:

      【解决方案2】:

      将分隔符设置为\n\n 将导致scanner.next() 将整个文件作为一个字符串返回,因为没有找到双新行。将分隔符设置为从未找到的任何内容都会产生相同的行为。

      接下来,使用split("\n") 拆分该字符串,并且该数组将包含文件中每行的一个条目。

      这样可以写得更干净

      try (Scanner scanner = new Scanner(new File(args[0]))) {
          while (scanner.hasNextLine()) {
              String row = scanner.nextLine();
              for (int col = 0; col < row.length(); col++) {
                  System.out.print(row.charAt(col) + " ");
              }
              System.out.println();
          }
      }
      

      【讨论】:

        【解决方案3】:

        我不明白您为什么将splitScanner 一起使用。第二个做第一个应该做的。

        改为使用\n 作为Scanner 的分隔符,但由于您使用的是next(),这意味着您应该迭代Scanner,直到没有更多可扫一扫。

        split 真的让你失去了使用Scanner 的所有兴趣。您只需读取整个文件一次,然后在所有文件都在内存中时将其拆分。这可能会导致大文件出现内存异常。

        未经测试,但这样的东西应该可以工作:

        import java.util.*;
        import java.io.*;
        
        public class Test {
        
          public static void main(String[] args )  throws Exception {
            Scanner scanner = new Scanner(new File(args[0]) );
            scanner.useDelimiter("\n");   
        
            while (scanner.hasNext()) {
                String row = scanner.next();
        
                for(int col = 0; col < row.length(); col++) {
                    System.out.print(row.charAt(col) + " ");
                }
                System.out.println();
            }
            scanner.close();
          } 
        }
        

        【讨论】:

          【解决方案4】:

          案例1:你使用scanner.useDelimiter("\n\n"); "\n\n" 是在文件中找不到的分隔符,因此第一个scanner.next() 将为您提供整个文件!

          当您在整个文件上使用 .split("\n") 时,它会为您提供在文件中找到的由“\n”分割的元素数组,这不知何故让您认为您的代码正在运行。

          import java.util.*;
          import java.io.*;
          
          public class Test {
          
            public static void main(String[] args )  throws Exception {
              Scanner scanner = new Scanner(new File(args[0]) );
              scanner.useDelimiter("\n\n");   
              String[] grid = scanner.next().split("\n");
              scanner.close();
          
              for(int row = 0; row < grid.length; row++) {
                  for(int col = 0; col < grid[row].length(); col++) {
                      System.out.print(grid[row].charAt(col) + " ");
                  }
                  System.out.println();
              }
            } 
          }
          

          案例 2:当您使用 scanner.useDelimiter("\n")scanner.next() 时,扫描仪会返回第一行,因为扫描仪已找到分隔符并逐行为您提供数据。

          现在当你使用scanner.next().split("\n"); 时,正则表达式“\n”不匹配,你又得到了第一行的整个字符串,这让你认为你的代码不起作用。

          如果你想读取文件,你应该在某个答案中指定的 while 循环中使用scanner.hasNext()

          【讨论】:

          • 是否有任何用例证明案例 1 的合理性?缓冲读数可能会起作用。加上大文件的潜在内存问题。
          • 是的,我不知道为什么 op 这样做,可能是在运行别人的代码进行学习。
          【解决方案5】:

          通过使用分隔符“\n\n”,您可以告诉扫描器在此处拆分标记。我的假设是输入文件是一个 Uninx 样式文件(所以换行符是 \n),它的末尾有两个换行符或某处有一个空行。

          因此,scanner.next() 基本上会在末尾(或空行)返回一个标记,然后逐行拆分。

          因此,更好的方法可能是:

          Scanner scanner = new Scanner(new File(args[0]) );
          scanner.useDelimiter("\n");
          List<String> grid = new ArrayList<>();
          while (scanner.hasNext()) {
              grid(scanner.next());
          }   
          scanner.close();
          

          您的代码只会处理文件的内容,直到有两个“\n\n”为止。

          【讨论】:

          • 如果输入为Hello\n\nWorld,您将获得"Hello""""World"的令牌。它不会停留在\n\n
          • 没错。我的建议适用于 '\n\n' 仅出现在文件末尾而不是中间某处的情况。
          猜你喜欢
          • 2012-09-02
          • 1970-01-01
          • 2011-10-04
          • 1970-01-01
          • 2011-03-04
          • 2016-07-09
          • 1970-01-01
          • 1970-01-01
          • 2014-04-12
          相关资源
          最近更新 更多