• Advertisement

Archived

This topic is now archived and is closed to further replies.

A File I/O Question

This topic is 5682 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey, Currently, I am working on a 3D tile-based game. At the moment, I have my map stored in an array like so:
1111111111
1000000101
1111001101
1001011001
1101010011
1111001111
1000110001
1000111101
1110011011
1111111111

note: it is actually in the proper array format (char map[10][10] = {{1, 1, 1, 1 ........
 
Now, a problem is developing. I want to store my array in a text file, so I tried that, but it wouldn''t store it in an array, just read the numbers. My question is this: how do I read a set of numbers in a text file and store them in an array? Thanks

Share this post


Link to post
Share on other sites
Advertisement
Hello,
Try this...

  
ifstream infile("mapdata.txt",ios::in);
//substitute your file name for "mapdata.txt"


if(infile == NULL)
//error,file did not open...

infile.close();

//file opened correctly...

for(int x=0;x<10;x++)
for(int y=0;y<10;y++)
infile>>array2d[x][y];

infile.close();

also, i noticed you were using char's instead of int's. Try switching your array to integers instead.
good luck

[edited by - shdaga on June 29, 2002 3:36:07 AM]

[edited by - shdaga on June 29, 2002 3:36:52 AM]

Share this post


Link to post
Share on other sites
Youll have to be a little more careful actually.
If your map is not always of same size, you will need to either write the size of the map first in the file, or before reading seek to the end and store that position so you know how large the file is(and thus how big a map it would make). Then you allocate the array with new using the information youve gained.

Also id suggest that you read/write in binary mode(use the ios::binary flag). You then use the write/read methods of the fstream object to read/write the array to/from file.

Btw, using chars will work just fine as long as you are okay with only having 256 different tiles(-127 to 128) you might want to use an unsigned char instead though(0-255), because it makes more sense for numbering tiles.

If you want to read up on file I/O check
http://www.cplusplus.com/ref/#libs under iostream library

C/C++ Runtime library reference|Boost utility libraries|SGI STL Reference

[edited by - ziphnor on June 29, 2002 4:20:10 AM]

Share this post


Link to post
Share on other sites
Well, actually all my maps are the same size, so do I still need to do all that or will what I am doing be fine?

Also, what''s the difference whether I do binary mode or not?

Share this post


Link to post
Share on other sites
You dont have to worry about dynamic allocation if all the maps are of the same size.(So the example given earlier will work just fine).

As to writing in binary vs. in text mode:
If you write the number 1 in text mode, what will ACTUALLY be written is the character code for the number 1.
If you write in binary mode the number 1 will be written as the binary representation of 1(ie 00000001 if your number is a byte).

Binary representation have some advantages in that you can write data directly from a file into the memory location and use it right away.(ie you could just use the read method of the fstream object, hand it your array pointer, tell it how much to read and it would write the whole thing from the file directly into memory).

Share this post


Link to post
Share on other sites
heres how I do mine :
my .map file is simply a txt file that looks like that
1 1 1 1 1
1 0 0 0 1
1 0 0 0 0 and so on, you can put any number in there so theres no
limit to what your map file can do. IE 255 could be a town tile that teleports you to a specific city etc...


ifstream worldmap;
worldmap.open("map2.map");

if(worldmap.fail())
cout << "Error : Could not find map2.txt";

int number;

for(int y= 0; y < MAP_SIZE_Y; ++y)
{
for(int x= 0; x < MAP_SIZE_X; ++x)
{
worldmap >> number;
map[x][y]= number;
}

worldmap.get();

}

worldmap.close();



Share this post


Link to post
Share on other sites
Again, the above text file examples will work just fine, and for such small datastructure as a 10x10 array it wont be a problem, on the other hand if you are for example storing a 1000x1000 char array then it might come in handy to read the whole array with one read(for performance reasons).
Also should the array be something other than a char(ie single byte) array then binary mode makes a whole lot more sense.

Share this post


Link to post
Share on other sites
Hello peeps,
Just to play the opposite of Ziphnor, one of the main reasons you can write to your map files in text mode is so you can easily see what your map may physically look like. It makes editing or creating small maps easier. But I do agree with Ziphnor, as soon as you have another way of creating your maps, i.e. not using notepad and just plugging in numbers, go ahead and store them in binary format. Also, look into making your maps dynamic, it will help in the long run, when you finally do decide to make arbitrarily sized maps.

Share this post


Link to post
Share on other sites
If these numbers are all 0s and 1s, it''s a better idea to use bools or chars to make your program a little bit more efficient. I''m an efficiency freak :D.

Share this post


Link to post
Share on other sites
Hey,

I had the same question as well on reading maps. I am doing a top down puzzle game. I want to have a level editor. Now that I know how to load the levels, that helps a lot, but how do I save a level that is made in the level editor? My levels are going to be stored in numbers (an array)... I will define the numbers as stuff like LEVEL_FLOOR for easy refrence. How would I go about saving a level I have made (I think I asked that twice... anyway)

- Thanks

Share this post


Link to post
Share on other sites
Hello,
Well, its pretty much just the reverse of loading a file, but here is a code example...Hope it helps


  
ofstream outfile("myMapData.txt",ios::out)
//replace myMapData.txt with whatever name you want...

if(outfile == NULL)
//error could not create file for whatever reason

outfile.close();
for(int x=0; x<mapWidth; x++)
for(int y=0; y<mapHeight; y++)
outfile << myMapDataArray2D[x][y];

outfile.close();

Now check your file to see if things output correctly...
If you have any other questions let us know.
Have fun.

Share this post


Link to post
Share on other sites
quote:

If these numbers are all 0s and 1s, it''s a better idea to use bools or chars to make your program a little bit more efficient. I''m an efficiency freak :D.



Just thought id mention that the original poster did in fact use chars.

Share this post


Link to post
Share on other sites
Thanks a lot for the help. It''s working pretty good now. Now, I have another question now.

All my levels are the same size. They are now each stored in a 30x30 array. A 0 is nothing, a 1 is a wall, and a 2 is a window. Now, when I get to the end of the first level, I want to load the next level, but do I have to have a routine like this for each one?

What I''m trying to say is, do I keep having to write this code for each level, or can I have the same code for all the levels?


Thanks

Share this post


Link to post
Share on other sites
If your levels are stored as different files simply pass the filename to your loading function. If on the other hand you wish to store them in the same file, you need to move about and find the level you wish to use. If all your levels are the same size then you do not need to worry about an index, or some other form of telling where a level end and begins. You simply have to move past N numbers of chars.

To load a level N
mapsize = 100*100 (chars);
filepointer = (N*mapsize);
....normal loading function ie read mapsize chars into array.

,Jay

Share this post


Link to post
Share on other sites

  • Advertisement