在 Java 中逐个字符地将文本文件读入二维数组

Reading a text file character by character into a 2D array in Java

作为我的面向对象 class 的一部分,我们将设计一款使用 TUI 最终实现 GUI 的战舰游戏。 根据设计,我们将从一个类似于 b

的文本文件中读取 AI 的飞船位置

 ABCDEFGHIJ
1
2 BBBB
3
4       C
5D      C
6D
7AAAAA
8     SSS  
9
0

其中字母代表不同的船只。我当前的游戏实现使用二维字符数组,因此我希望能够读取文本文件并创建相应的二维数组。我见过一些允许您读取下一个字符串或下一个整数的内置函数,但我只想逐个字符地读取它。有没有办法做到这一点? 提前致谢!

看看here.You这样可以一个字一个字的读。您需要了解新行。 http://docs.oracle.com/javase/tutorial/essential/io/charstreams.html

在我看来,最简单的方法是先逐行读取文件,然后逐字符读取这些行。通过使用内置实用程序,您可以避免处理新行的复杂性,因为它们因 OS/Editor.

而异

BufferedReader Docs

    BufferedReader fileInput = new BufferedReader(new FileReader("example.txt"));
    String s;
    while ((s = fileInput.readLine()) != null) {
        for (char c : s.toCharArray()) {
            //Read into array
        }
    }
    fileInput.close();
//Open file stream
FileReader in = new FileReader("fileName.txt");
BufferedReader br = new BufferedReader(in);

String line = ""; //Declare empty string used to store each line

//Read a single line in the file and store it in "line" variable
//Loop as long as "line" is not null (end of file)
while((line = br.readLine() != null) {
    //Iterate through string until the end
    //Can use a regular loop also
    for(char ch : line.toCharArray()) {
        //Do something with the variable ch
        if(ch == 'B')
            ;
        else if(ch == 'C')
            ;
        else if(ch == ' ')
            ;
        else
            ;
    }
}

大意是把问题分解成更简单的问题来解决。如果你有一个可以打开文件并读取一行的函数,那么你就解决了一个问题。接下来需要解决一个字符一个字符地遍历字符串的问题。这可以通过多种方式完成,但一种方式是使用 String class 的内置函数将 String 转换为字符数组。

唯一缺少的是打开文件时通常需要的 try{} catch{} 以及正确导入 classes:FileReader 和 BufferedReader。

@JudgeJohn 的回答很好——我会发表评论,但不幸的是我不能。首先逐行阅读将确保任何系统细节(如换行符的实现)都由 Java 的各种库处理,这些库知道如何做得很好。在文件的某种 reader 上使用 Scanner 将允许轻松枚举行。在此之后,逐个字符读取获得的String应该没有问题,例如使用toCharArray()方法。

一个重要的补充 - 当使用 StreamReader 对象,以及 Scanners 在它们上面时,你的代码很好地处理过程的结束通常很重要 - 处理文件句柄等系统资源。这是在 Java 中使用这些 类 的 close() 方法完成的。现在,如果我们完成阅读并调用 close(),当事情按计划进行时这一切都很好,但是可能会抛出异常,导致方法在调用 close() 方法之前退出.一个好的解决方案是 try - catchtry - finally 块。例如

Scanner scanner = null;
try {
    scanner = new Scanner(myFileStream);
    //use scanner to read through file
    scanner.close();
} catch (IOException e) {
    if (scanner != null) scanner.close(); //check for null in case scanner never got initialised.
}

更好的是

Scanner scanner = null;
try {
    scanner = new Scanner(myFileStream);
    //use scanner to read through file
} finally {
    if (scanner != null) scanner.close(); //check for null in case scanner never got initialised.
}

无论 try 块如何退出,finally 块总是被调用。更好的是,Java 中有一个 try-with-resources 块,它是这样的:

try (Scanner scanner = new Scanner(myFileStream)) {
    //use scanner to read through file
}

这个程序完成所有空值检查,finallyclose() 的调用。非常安全,输入速度很快!

您可以使用 Scanner 来读取单个字符,如下所示:

scanner.findInLine(".").charAt(0)

棋盘是一个 11x11 的字符 (char[][] board = new char[11][11]),因此您在阅读字符时必须跟踪所在的行和列。读完第 11 个字符后,您就会知道何时转到下一行。

代码示例:

public static void main(String[] args) throws Exception {
    String file = 
        " ABCDEFGHIJ\n" +
        "1          \n" +
        "2 BBBB     \n" +
        "3          \n" +
        "4       C  \n" +
        "5D      C  \n" +
        "6D         \n" +
        "7AAAAA     \n" +
        "8     SSS  \n" +
        "9          \n" +
        "0          \n";

    char[][] board = new char[11][11];
    Scanner scanner = new Scanner(file);

    int row = 0;
    int col = 0;
    while (scanner.hasNextLine()) {
        // Read in a single character
        char character = scanner.findInLine(".").charAt(0);
        board[row][col] = character;
        col++;

        if (col == 11) {
            // Consume the line break
            scanner.nextLine();

            // Move to the next row
            row++;
            col = 0;    
        }
    }

    // Print the board
    for (int i = 0; i < board.length; i++) {
        System.out.println(new String(board[i]));
    }
}

结果:

 ABCDEFGHIJ
1          
2 BBBB     
3          
4       C  
5D      C  
6D         
7AAAAA     
8     SSS  
9          
0