如何将文件中的字符写入二维数组?
How can I write characters from a file to a 2D array?
我目前正在尝试通过将文件加载到数组中来从文件加载 "map"。我可以在没有数组的情况下打印文件本身,但我的项目是制作一个基于 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();
}
}
}
当它returns输入时,地图完全乱了,毫无意义。它应该看起来像:
#########################
#.......................#
#......#................#
########................#
#......#................#
#......#................#
#......#................#
#.######................#
#.......................#
#########################
但看起来像:
##########
##########
#####
#..
..........
..........
.#
#.....
.#........
........#
########.
..........
.....#
#.
.....#....
..........
..#
#....
..#.......
.........#
#......#
..........
......#
#
.######...
..........
...#
#...
..........
..........
#
#######
我最初将 for 循环包裹在 while 循环中,但当然它只打印了“#”符号。我只需要它来打印地图并将字符正确保存到数组中。
你有两个问题。
首先:你所有的阅读和打印输出都有点乱。
您将线的长度存储为 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(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 您不希望 width
和 height
成为 static
(参见链接教程)。
我目前正在尝试通过将文件加载到数组中来从文件加载 "map"。我可以在没有数组的情况下打印文件本身,但我的项目是制作一个基于 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();
}
}
}
当它returns输入时,地图完全乱了,毫无意义。它应该看起来像:
#########################
#.......................#
#......#................#
########................#
#......#................#
#......#................#
#......#................#
#.######................#
#.......................#
#########################
但看起来像:
##########
##########
#####
#..
..........
..........
.#
#.....
.#........
........#
########.
..........
.....#
#.
.....#....
..........
..#
#....
..#.......
.........#
#......#
..........
......#
#
.######...
..........
...#
#...
..........
..........
#
#######
我最初将 for 循环包裹在 while 循环中,但当然它只打印了“#”符号。我只需要它来打印地图并将字符正确保存到数组中。
你有两个问题。
首先:你所有的阅读和打印输出都有点乱。
您将线的长度存储为 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(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 您不希望 width
和 height
成为 static
(参见链接教程)。