1

作为我的面向对象课程的一部分,我们将设计一个使用 TUI 最终实现 GUI 的战舰游戏。根据设计,我们将从一个类似于 b 的文本文件中读取 AI 的船舶位置

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

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

4

5 回答 5

3

在我看来,最简单的方法是首先逐行读取文件,然后逐字符读取这些行。通过使用内置实用程序,您可以避免处理新行的复杂性,因为它们因操作系统/编辑器而异。

BufferedReader 文档

    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();
于 2015-08-02T02:12:21.893 回答
2

看看这里。您可以通过这种方式逐字阅读。您需要了解新线路。 http://docs.oracle.com/javase/tutorial/essential/io/charstreams.html

于 2015-08-02T02:07:46.033 回答
2
//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 类的内置函数将 String 转换为字符数组。

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

于 2015-08-02T02:14:51.613 回答
2

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

一个重要的补充——当使用StreamReader对象时Scanner,你的代码很好地处理进程的结束通常很重要——处理文件句柄等系统资源。这是在 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.
}

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

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

这个执行所有检查空值finally和调用close(). 非常安全,打字很快!

于 2015-08-02T02:26:37.113 回答
1

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

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          
于 2015-08-02T02:40:35.963 回答