【问题标题】:Reading a text file with Scanner and turning it into a 2d int array使用 Scanner 读取文本文件并将其转换为 2d int 数组
【发布时间】:2021-04-04 21:47:27
【问题描述】:

我正在尝试创建一个程序,该程序从 JFileChooser 读取文本文件,然后将其转换为 2d int 数组。文本文件可能如下所示:

000000

000000

001110

011100

000000

我需要该文件能够读取不确定行和列的 txt 文件。这是我尝试过的代码,但是当这种情况发生时,我的 GUI 什么都不做,它会中断并且在关闭时不再退出。

为了澄清,我希望每个单个数字(1 或 0)都打印为数组的一个元素,并且我希望文件的每一行都是数组中的一行。

try {
    File file = new File(String.valueOf(fc.getSelectedFile()));
    Scanner reader = new Scanner(file);
    cols = reader.nextLine().length();
    while (reader.hasNextInt()) {
        size++;
    }
    rows = size / cols;
    int[][] iBoard = new int[rows][cols];
    while (reader.hasNextInt()) {
        for (int i = 0; i < iBoard.length; i++) {
            for (int j = 0; j < iBoard[0].length; j++) {
                iBoard[i][j] = reader.nextInt();
            }
        }
    }
    reader.close();
                    
} catch (FileNotFoundException q) {
     q.printStackTrace();
}

【问题讨论】:

  • 那么,文件中的数据列在哪里?我只看到一列数据。还是一行中的每个数字都是一列?二维数组就像一个有行和列的表格。
  • 每个数字都是一列。我希望它打印为 {0,0,0,0,0,0}、{0,0,0,0,0,0} 等......

标签: java arrays swing


【解决方案1】:

这是我的做法。

package com.tralamy.stackoverflow;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;

public class FileToArray {

    public static void main(String[] args) throws IOException {
        // In your case, replace "array.txt" by String.valueOf(fc.getSelectedFile())
        File file = new File("array.txt"); // Creating a new File for the array

        Scanner fileScan = new Scanner(file); // Creating a Scanner Object from the file

        ArrayList<ArrayList<Integer>> arrays = new ArrayList<>(); // The 2d Array

        // For each line of the file
        while (fileScan.hasNextLine()) {
            String line = fileScan.nextLine(); // Store the line content to a String variable
            ArrayList<Integer> array = new ArrayList<>(); // One dimension Array of Integer

            // For each character in the line
            for (Character ch : line.toCharArray()) {

                /*
                * Integer.parseInt parse a String to a integer
                * To get a string from a Character I use toString method
                * I then add the value to the array*/
                array.add(Integer.parseInt(ch.toString()));
            }
            arrays.add(array); // add the one dimension to the two dimensions array
        }
        fileScan.close(); // Close the scanner
        
        // To print the result, uncomment the line below
        System.out.println(arrays);
    }
}

array.txt

000000
000000
001110
011100
000000

【讨论】:

    【解决方案2】:

    您可以将每一行保存到List&lt;String&gt; 中,而不是尝试一次读取每个int。然后遍历此列表,获取每个 String 中的每个 char 并将其放入您的二维数组中。

    【讨论】:

      【解决方案3】:

      正如已经证明的那样,这种事情最好使用整数的二维数组列表 (ArrayList&lt;ArrayList&gt;&gt;) 或整数的二维列表接口 (List&lt;List&lt;Integer&gt;&gt;)。这显然是要走的路,因为您不需要读取数据文本文件两次,一次是为了获取文件中的实际数据行数,一次是为了检索数据。通过使用像 ArrayListList 这样的收集机制,您无需为它们分配大小,它们可以动态增长。但是,如果您仍然一心想要使用 2D 整数数组 (int[][]),那么您可以将集合完全转换为该数组。

      这是我的想法(利用您提供的代码方案):

      /**
       * Allows the User to select a file using a file chooser navigation dialog. 
       * The selected file contents will then be placed into a 2D int Array. The 
       * file selected <u>must</u> contain 1 numerical value per text file Line,
       * for example: <b>100100010</b>. Any blank lines in the file are ignored.<br>
       * 
       * @param fileLocatedInFolder (Optional - String - Default is: "C:\") The 
       * directory path for where the JFileChooser lists files in when it opens. 
       * If nothing is supplied then the JFileChooser will start in the root 
       * directory of drive C.<br>
       * 
       * @return (Two Dimensional int Array) A 2D int[][] array of the file contents.
       * Each file line is an array row. Each numerical value in each file line is 
       * split into columnar digits for the 2D int array.
       */
      public int[][] get2DArrayFromFile(String... fileLocatedInFolder) {
          String fileChooserStartPath = "C:\\";
          if (fileLocatedInFolder.length > 0) {
              if (new File(fileLocatedInFolder[0]).exists() && new File(fileLocatedInFolder[0]).isDirectory()) {
                  fileChooserStartPath = fileLocatedInFolder[0];
              }
          }
          JFileChooser fc = new JFileChooser(fileChooserStartPath);
          fc.showDialog(this, "Open");
          if (fc.getSelectedFile() == null) {
              return null;
          }
          String filePath = fc.getSelectedFile().getAbsolutePath();
          ArrayList<ArrayList<Integer>> rowsList = new ArrayList<>();
          int[][] intArray = null;
      
          // 'Try With Resources' use here to auto-close reader.
          ArrayList<Integer> columnsList;
          int row = 0;
          int col = 0;
          try (Scanner reader = new Scanner(fc.getSelectedFile())) {
              String fileLine;
              while (reader.hasNextLine()) {
                  fileLine = reader.nextLine();
                  fileLine = fileLine.trim(); // Trim the line
                  // If the file line is blank, continue to 
                  // the next file line...
                  if (fileLine.isEmpty()) {
                      continue;
                  }
                  columnsList = new ArrayList<>();
                  col = 0;
                  String[] lineParts = fileLine.split("");
                  for (int i = 0; i < lineParts.length; i++) {
                      if (lineParts[i].matches("\\d")) {
                          columnsList.add(Integer.valueOf(lineParts[i]));
                      }    
                      else {
                          System.err.println(new StringBuilder("Ivalid data detected ('")
                                  .append(lineParts[i]).append("') on file line ")
                                  .append((row + 1)).append(" in Column #: ").append((col + 1))
                                  .append(System.lineSeparator()).append("Ignoring this data cell!")
                                  .toString());
                      }
                      col++;
                  }
                  row++;
                  rowsList.add(columnsList);
              }
          } 
          catch (FileNotFoundException ex) {
              Logger.getLogger("get2DArrayFromFile() Method Error!")
                               .log(Level.SEVERE, null, ex);
          }
          
          //Convert 2D Integer ArrayList to 2D int Array
          intArray = new int[rowsList.size()][rowsList.get(0).size()];
          for (int i = 0; i < rowsList.size(); i++) {
              for (int j = 0; j < rowsList.get(i).size(); j++) {
                  intArray[i][j] = rowsList.get(i).get(j);
              }
          }
          rowsList.clear();
          return intArray;
      }
      

      并使用上述方法:

      int[][] iBoard = get2DArrayFromFile();
      
      // Display 2D Array in Console Window:
      if (iBoard != null) {
          for (int i = 0; i < iBoard.length; i++) {
              System.out.println(Arrays.toString(iBoard[i]).replaceAll("[\\[\\]]", ""));
          }
      }
      

      如果您的数据文件与您展示的一样:

      000000
      
      000000
      
      001110
      
      011100
      
      000000
      

      那么控制台窗口的输出将是:

      0, 0, 0, 0, 0, 0
      0, 0, 0, 0, 0, 0
      0, 0, 1, 1, 1, 0
      0, 1, 1, 1, 0, 0
      0, 0, 0, 0, 0, 0
      

      【讨论】:

        猜你喜欢
        • 2016-07-17
        • 2021-05-20
        • 2016-03-11
        • 1970-01-01
        • 2011-10-02
        • 2014-09-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多