Loading a tile-maps from text files.

Started by
7 comments, last by Kwizatz 11 years, 9 months ago
I know this question has been asked endlessly on these forums, but I have been goggling like crazy a bit of snippet och explanation around the stream class methods. Most code that I found out there didn't include a delimiter and did only handle single digit numbers. ( 0 through 9 is quite limiting ).

Basically I want to store the map as accordingly to this:

/* Some other data to read here, like map width and height ect ect */

0,0,0,0,1,0,0,0,0,0,0
0,0,0,0,1,0,0,0,0,0,0
0,0,0,0,1,0,0,0,0,0,0
0,0,0,0,1,2,2,2,0,0,0
0,0,0,0,1,2,2,2,0,0,0
0,0,0,0,1,1,1,1,1,1,1
0,13,13,0,0,0,0,0,0,0,0
0,0,13,13,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0


With ',' as the delimiter, but I'm not sure what methods to use to achieve this, it was quite straight fore-ward when I did it in C# though.
Also should I use string-stream for conversion from ( In my case the map is made out of unsigned char's giving me 1 byte per character and 0 - 255 possible tile ids to work with ) string to unsigned char? Or atoi()?

Hopefully someone kind could help me, thanks in advance!
Advertisement
I have some code in C++ that will load in a txt file and then place the wanted variables in the correct place if that is what you are looking for?
I would change all of your "," to just spaces,
here is a simple txt file and the code to read it
x y z
0 0 1
0 1 0
1 0 0


[source lang="cpp"]
vector<int> Xs;
vector<int> Ys;
vector<int> Zs;

void gLevel::loadFromFile(const char *filename)
{
std::ifstream file(filename);
int x,y,z
while(file >> x >> y >> z)
{
xS.push_back(x);
xS.push_back(y);
xS.push_back(z);
}
file.close();[/source]

Xs will have 0,0,1
Ys will have 0,1,0
Zs will have 1,0,0

understand? also the vectors i made to hold the variable is silly, but you can store them however you want.
Also remember to #include <ifstream>
You could also use strtok, it's a C style function but it gets the job done. You can also specify a delimiter this way.
@Canvas - Dosn't that only support single digit numbers?

@Mussi - Are their any downsides to actually using C-methods with C++ or is it categorized as "bad practice"? Anyhow It looks like a clean and simple way of reading a line, using strtok(); to delimit the values of the line and then just add it to my 2D Vector? :)
Are their another more C++ strict ways of doing this?

Thanks for the fast reply guys!
I'm not aware of a C++ alternative, but there are some things that you'll have to take into consideration when using strtok(). It's not thread safe, so be careful with that when mutli-threading. It also modifies the original string, it returns a pointer to the start of the token and places a null terminated character at the start of the delimiter, so if you need the original string for some reason(I don't think you do in your case) you'll have to make a copy or restore the string.

You could also write your own strtok() like function that's thread safe and doesn't modify the original string.
it will work, what it does is with the while statement it will first take the first input of the file which is 0 in the reply i put above, and place that 0 into x, the next value seperated by a space will go in to y and then z and then back x and so on and so forth, but if we were to put 10 231 7123
x would be 10 then y would be 231 and then z would be 7123, the while statement will read the first value and not stop until it hits a white space, then it will take in the next value and so on.
If you do not need it to be "human-readable", you could just read/write to a binary file...
Binary isn't to hard to work out, best way I think would just do a huge algorithm on the file as it is loaded, so if any does access and edit the file it will go wrong, and also do a hard code check on 3 random pieces of values in the file you know are correct.
You may want to look at the XPM file format, it pretty much has all of your requirements and since it uses C syntax, you could compile the maps right into your executable as resources.

There is a library for it which has a permisive BSD license and seems to have already been ported to Windows, though you will have to compile it yourself.

If anything it should give you some ideas to incorporate into your format.

In C++ you can use a combination of the std::string find_* and substr methods to tokenize your map data.

This topic is closed to new replies.

Advertisement