Robert Iannuzzi Robert Iannuzzi - 11 days ago 5
Java Question

How can I write characters from a file to a 2D array?

I'm currently trying to load a "map" from a file by loading it into an array. I can print the file itself without the array, but my project is to make an ASCII based game, so I need to have coordinates to place other objects on.

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();
}
}

}


When it returns input, the map is entirely out of order and makes no sense. It should look like:

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


But instead looks like:

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


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

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


I had it initially where the for loops were wrapped in a while loop, but of course then it only printed the '#' symbol. I just need it to print the map and save the characters into the array correctly.

Answer

You have two problems.

First: All of your reads and print-outs are a bit out of order.

You're storing the length of a line as the width in the X dimension, but then you have:

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

This is reading columns (y) first, so if each line in your file is supposed to be horizontal, you're reading them vertical by mistake. You need to swap the inner and outer for loop.

Then when you print you do it backwards too:

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

You're printing each column with a linebreak after it. So you'll need to switch those loops too.


Second: You're reading newlines as part of your tiles. read() doesn't care about line breaks.

So just read one line at a time. Then go through each character in that line and pack it into map at the appropriate location.


Btw, You also have this loop where you read all the lines to count them as a first pass. You don't really need to do that. You can do it all in one pass. It's up to you if you want to assume every line is the same length, or how to handle different length lines, but either way, if you use dynamically resizeable containers, like e.g. an ArrayList, you don't need to know how many lines are in the file ahead of time or how long each line is, you can add as you go (in this case you don't need to store the width and height at the top of the file separately, either -- personally I'm not a big fan of encoding duplicate info in a file if the info is otherwise readily available, e.g. if every line in the file is a row in your map you don't need to redundantly store the line count, it just adds more opportunities for inconsistencies and mistakes).

For example, you can pretty much do the whole thing in just a few lines if you want no real error checking:

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

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

But you probably want to verify line lengths and stuff. Here's a full demo (I forgot to close the file, don't forget to do that): http://ideone.com/K6s6NQ

PS You don't want width and height to be static (see linked tutorial).

Comments