level file

Recommended Posts

Aerts    100
I'm trying to make a C++ program that reads text (.txt) files. The text files are meant to represent the various things found in a game level (map). I need: 1)if possible a complete sourcecode that does this (or a link) or/and 2)some pointers about how to do this- especially what function/methods/structures to use.

Share on other sites
Sabonis    169
No one is going to do this for you... :/

#include <fstream>

//create input file stream
ifstream Input("filename.txt");

//make sure file is open
if(Input.is_open())
{
while(!Input.eof())
{
Input >> data structure of your choice;
//now just play around with input format and what you want to get out of the file
}
}
// dont forget to close the file when you're finished using it

Share on other sites
Squirm    481
Quote:
 I'm trying to make a C++ program that reads text (.txt) files. The text files are meant to represent the various things found in a game level (map). I need:

We need:
You to tell us what you actually want to do...

There are plenty of tutorials out there on reading files - what exactly is causing you problems?

Share on other sites
hplus0603    11347
Here's the typical parser loop for reading objects:

size_t size;char * text = read_file( "level.txt", &size );char * del = text;char * end = size+text;while( text < end ) {  get_object( text );}delete[] del;

The helper function to read a file into memory looks like this:

char * read_file( char const * fn, size_t * osize ){  FILE * f = fopen( fn, "rb" );  if( !f ) throw std::runtime_error( "Can't find file" );  fseek( f, 0 , 2 );  *osize = ftell( f );  fseek( f, 0, 0 );  char * ret = new char[*osize+1];  fread( ret, 1, *osize, f );  ret[*osize] = 0;  fclose( f );  return ret;}

"getting" and "object" from a text file means parsing the file. There are a number of ways to write a parser; the simplest is a recursive-descent parser ("RD").

// assuming syntax is:// obj-type obj-name {//   parameter value;//   parameter value;// }void get_object( char * & text ){  std::string type = get_token( text );  std::string name = get_token( text );  if( get_token( text ) != '{' ) throw std::runtime_error( "syntax error; '{' expected" );  std::list< std::pair< std::string, std::string > > params;  while( true ) {    std::string param = get_token( text );    if( tok == '}' ) break; // done    std::string value = get_token( text );    if( get_token( text ) != ';' ) throw std::runtime_error( "syntax error; ';' expected" );    params.push_back( std::pair< std::string, std::string >( param, value ) );  }  register_object( type, name, params );}

OK, all we need to know now is how to read a token from a character pointer. In the simplest case, we assume that tokens are non-whitespace, non-semicolon and non-brace characters, separated by semicolons, braces, or whitespace. To support strings with spaces in them, let's use double-quote for that, and backslash-doublequote to quote a quote.

std::string get_token( char const * & text ){  while( *text && isspace( *text ) ) ++text;  if( !*text ) throw std::runtime_error( "get_token() encountered end of file" );  if( *text == '{' || *text == '}' || *text == ';' ) { ++text; return std::string(text[-1], 1); }  bool quote = false;  bool backslash = false;  std::string ret;  while( *text ) {    if( !quote && !backslash ) {      if( *text == '{' || *text == '}' || *text == ';' || isspace( *text ) ) break;      if( *text == '"' ) quote = true;      else if( *text == '\\' ) backslash = true;      else ret.push_back( *text );    }    else if( backslash ) {      ret.push_back( *text );      backslash = false;    }    else {      if( *text == '"' ) quote = false;      else ret.push_back( *text );    }    ++text;  }  if( quote || backslash ) throw std::runtime_error( "get_token() found end of file within string value" );  return ret;}

It's really not that complicates.

So, what do you do with the parsed objects that you get into register_object()? Well, that's where the specifics of your program comes in.

[Edited by - hplus0603 on March 26, 2006 5:10:35 PM]

Share on other sites
andrew_480    163
What advantages does using c-style FILE* have over streams?

Share on other sites
hplus0603    11347
Quote:
 Original post by andrew_480What advantages does using c-style FILE* have over streams?

Purely preference. For reading a single file into memory, using streams or using FILE* are equivalent.

Share on other sites
Mike Bossy    697
I would look into using XML instead of just plain text to store your data. As long as you don't end up storing megabytes of text data in this file then using XML will make things easier to read and parse without too much over head.

There are a number of libraries out there that are already written to do the parsing that you want. Check out TinyXML on google. That's what I use and it works like a champ.

In the future if your level files get too big you'll want to move to a binary format anyways. At that point you can write a little utility to convert your XML files into an appropriate binary format and vice versa. This keeps it easy to read while doing your design work.

Share on other sites
Aerts    100
To Squirm: it's the first time I try to read a mapfile (the game that uses it is win32 console, without SDL, Allegro etc- a text game). All I need is a program that can read this:

health 100
ammo 50
damage 10

I need to know:
1 HOW to read the file: char-by-char or line by line, using delimitators?
2 how to handle whitespaces, newlines etc.

Also I'd appreciate links to some tutorials- I've searched but only found advanced tutorials/sourcecode.
Thanks.