【问题标题】:Java Reading 2D array in from file, numbers separated by commaJava 从文件中读取二维数组,数字用逗号分隔
【发布时间】:2014-01-23 05:32:54
【问题描述】:

这是我发现有助于读取二维数组的一些代码,但我遇到的问题是这仅在读取结构如下的数字列表时才有效:

73
56
30
75
80
ect..

我想要的是能够读取结构如下的多行:

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

我只想将每一行作为一个数组导入,同时在文本文件中像数组一样构建它们。 我读过的所有内容都说要使用 scan.usedelimiter(",");但是在我尝试使用它的任何地方,程序都会直接抛出回复“错误转换数字”的问题。如果有人可以提供帮助,我将不胜感激。我还看到了一些关于对缓冲阅读器使用 split 的信息,但我不知道哪个会更好/为什么/如何使用。

    String filename = "res/test.txt"; // Finds the file you want to test.


    try{
        FileReader ConnectionToFile = new FileReader(filename);
        BufferedReader read = new BufferedReader(ConnectionToFile);
        Scanner scan = new Scanner(read);

        int[][] Spaces = new int[10][10];
        int counter = 0;
        try{
            while(scan.hasNext() && counter < 10)
            {
                for(int i = 0; i < 10; i++)
                {
                    counter = counter + 1;
                    for(int m = 0; m < 10; m++)
                    {
                        Spaces[i][m] = scan.nextInt();
                    }
                }
            }
            for(int i = 0; i < 10; i++)
            {
                //Prints out Arrays to the Console, (not needed in final)
                System.out.println("Array" + (i + 1) + " is: " + Spaces[i][0] + ", " + Spaces[i][1] + ", " + Spaces[i][2] + ", " + Spaces[i][3] + ", " + Spaces[i][4] + ", " + Spaces[i][5] + ", " + Spaces[i][6]+ ", " + Spaces[i][7]+ ", " + Spaces[i][8]+ ", " + Spaces[i][9]);
            }
        } 
        catch(InputMismatchException e)
        {
            System.out.println("Error converting number");
        }
        scan.close();
        read.close();
    }
    catch (IOException e)
    {
    System.out.println("IO-Error open/close of file" + filename);
    }
}

【问题讨论】:

  • 你为什么不把整个东西读成一个字符串。在","s上拆分字符串,然后将其转换为二维数组?
  • 在你的 catch 语句中而不是仅仅打印出“错误转换数字”使用 e.printStackTrace()。或 System.out.println(e)。这样你就可以真正看到错误是什么。
  • 你的问题解决了吗???

标签: java arrays split 2d delimiter


【解决方案1】:

我在这里提供我的代码。

public static int[][] readArray(String path) throws IOException {
    //1,0,1,1,0,1,0,1,0,1
    int[][] result = new int[3][10];
    BufferedReader reader = new BufferedReader(new FileReader(path));
    String line = null;
    Scanner scanner = null;
    line = reader.readLine();
    if(line == null) {
        return result;
    }
    String pattern = createPattern(line);
    int lineNumber = 0;
    MatchResult temp = null;
    while(line != null) {
        scanner = new Scanner(line);
        scanner.findInLine(pattern);
        temp = scanner.match();
        int count = temp.groupCount();
        for(int i=1;i<=count;i++) {
            result[lineNumber][i-1] = Integer.parseInt(temp.group(i));
        }
        lineNumber++;
        scanner.close();
        line = reader.readLine();
    }
    return result;
}

public static String createPattern(String line) {
    char[] chars = line.toCharArray();
    StringBuilder pattern = new StringBuilder();;
    for(char c : chars) {
        if(',' == c) {
            pattern.append(',');
        } else {
            pattern.append("(\\d+)");
        }
    }
    return pattern.toString();
}

【讨论】:

    【解决方案2】:

    以下代码 sn-p 可能会有所帮助。基本思想是读取每一行并解析出 CSV。请注意,CSV 解析通常很困难,并且主要需要专门的库(例如 CSVReader)。但是,手头的问题相对简单。

    try {
       String line = "";
       int rowNumber = 0;
       while(scan.hasNextLine()) {
           line = scan.nextLine();
           String[] elements = line.split(',');
           int elementCount = 0;
           for(String element : elements) {
              int elementValue = Integer.parseInt(element);
              spaces[rowNumber][elementCount] = elementValue;
              elementCount++;
           } 
           rowNumber++;
       }
    } // you know what goes afterwards
    

    【讨论】:

      【解决方案3】:

      由于是逐行读取的文件,所以每行都使用分隔符“,”读取。

      所以在这里您只需创建一个新的扫描仪对象,使用分隔符“,”传递每一行

      代码看起来像这样,在第一个 for 循环中

                 for(int i = 0; i < 10; i++)
                      {
                          Scanner newScan=new Scanner(scan.nextLine()).useDelimiter(",");
                          counter = counter + 1;
                          for(int m = 0; m < 10; m++)
                          {
                              Spaces[i][m] = newScan.nextInt();
                          }
                      }
      

      【讨论】:

        【解决方案4】:

        使用 Scanner 中的 useDelimiter 方法将分隔符设置为“,”而不是默认的空格字符。 根据给定的示例输入,如果二维数组中的下一行从新行开始,而不是使用“,”,则必须指定多个分隔符。

        例子:

         scan.useDelimiter(",|\\r\\n");
        

        这会将分隔符设置为“,”和回车+换行符。

        【讨论】:

          【解决方案5】:

          为什么要使用扫描仪扫描文件?你已经有一个BufferedReader

          FileReader fileReader = new FileReader(filename);
          BufferedReader reader = new BufferedReader(fileReader);
          

          现在您可以逐行读取文件。棘手的一点是你想要一个int的数组

          int[][] spaces = new int[10][10];
          String line = null;
          int row = 0;
          while ((line = reader.readLine()) != null)
          {
              String[] array = line.split(",");
              for (int i = 0; i < array.length; i++)
              {
                  spaces[row][i] = Integer.parseInt(array[i]);
              }
              row++;
          }
          

          另一种方法是对各个行使用Scanner

          while ((line = reader.readLine()) != null)
          {
              Scanner s = new Scanner(line).useDelimiter(',');
              int col = 0;
              while (s.hasNextInt())
              {
                  spaces[row][col] = s.nextInt();
                  col++;
              }
              row++;
          }
          

          另一件值得注意的事是您使用的是int[10][10];这需要您提前知道文件的长度。 List&lt;int[]&gt; 将删除此要求。

          【讨论】:

          • 非常感谢您的快速回复。缓冲阅读器 sn-p 工作完美,更有意义。我唯一的另一个问题是,“使用缓冲读取器与扫描器有什么好处?”
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多