如何将文件中的字符写入2D数组?

时间:2016-11-23 18:29:05

标签: java arrays io bufferedreader

我正在尝试通过将其加载到数组中来加载文件中的“地图”。我可以在没有数组的情况下打印文件,但我的项目是制作基于ASCII的游戏,所以我需要有坐标来放置其他对象。

import java.io.*;

public class Map
{
    private static String mapFile = "";

    private static File currentMap;
    private static BufferedReader br;


    private static int width;
    private static int height;

    char[][] map;

    public Map(String newMap) throws IOException
    {
        int c;
        char mapPiece;
        mapFile = newMap;
        currentMap = new File(mapFile);
        try{
            br = new BufferedReader(new FileReader(currentMap));
            String line;
            width = 0;
            height = 0;

            while((line = br.readLine()) != null)
            {
                height++;
                width = line.length();
            }

            map = new char[width][height];

            br.close();
            br = new BufferedReader(new FileReader(currentMap));

            for(int x = 0; x < width; x++)  
            {
                for(int y = 0; y < height; y++)
                {   
                    if((c = br.read()) != -1)
                        map[x][y] = (char) c;
                }                   
            }

            br.close();
        } finally {}

        System.out.println();

        for(int x = 0; x < width; x++)  
        {
            for(int y = 0; y < height; y++)
            {   
                System.out.print(map[x][y]);
            }
            System.out.println();
        }
    }

}

当它返回输入时,地图完全无序并且毫无意义。它应该看起来像:

#########################
#.......................#
#......#................#
########................#
#......#................#
#......#................#
#......#................#
#.######................#
#.......................#
#########################

但看起来像:

##########
##########
#####
#..
..........
..........
.#
#.....
.#........
........#


########.
..........
.....#
#.
.....#....
..........
..#
#....
..#.......
.........#

#......#
..........
......#
#
.######...
..........
...#
#...
..........
..........
#
#######

我最初在for循环中包含了for循环,但当然它只打印了'#'符号。我只需要它来打印地图并将字符正确地保存到数组中。

1 个答案:

答案 0 :(得分:2)

你有两个问题。

首先:您的所有读取和打印输出都有点乱。

您将行的长度存储为X维度中的宽度,但是您有:

for(int x = 0; x < width; x++)  
        {
            for(int y = 0; y < height; y++)
            {   
                if((c = br.read()) != -1)
                    map[x][y] = (char) c;
            }                   
        }

这是首先读取列(y),因此如果文件中的每一行都应该是水平的,那么你会误读它们。你需要交换内部和外部for循环。

然后当你打印时,你也会倒退:

 for(int x = 0; x < width; x++)  
    {
        for(int y = 0; y < height; y++)
        {   
            System.out.print(map[x][y]);
        }
        System.out.println();
    }

您正在打印每个列后面的换行符。所以你也需要切换这些循环。

第二个:您正在阅读换行符作为拼贴的一部分。 read()并不关心换行符。

所以一次只读一行。然后浏览该行中的每个字符并将其打包到map的适当位置。

顺便说一下,你也有这个循环,在那里你读取所有的行来计算它们作为第一遍。你真的不需要这样做。你可以一次完成所有这一切。如果你想假设每一行都是相同的长度,或者如何处理不同长度的行,这取决于你,但无论如何,如果你使用动态可调整大小的容器,例如一个ArrayList,您不需要提前知道文件中有多少行或每行多长,您可以随意添加(在这种情况下,您不需要存储宽度和文件顶部的高度分开,或者 - 我个人不是编码文件中重复信息的忠实粉丝,如果信息是可用的,例如,如果文件中的每一行都是地图中的一行你不需要冗余地存储行数,它只会增加更多的不一致和错误的机会。)

例如,如果您不想进行真正的错误检查,您可以在几行中完成所有操作:

List<char[]> map = new ArrayList<char[]>();

String line;
while ((line = br.readLine()) != null)
    map.add(line.toCharArray());

但您可能想要验证线路长度和内容。这是一个完整的演示(我忘了关闭文件,不要忘记这样做):http://ideone.com/K6s6NQ

PS您不希望widthheightstatic(请参阅链接教程)。