• Advertisement
Sign in to follow this  

Need help working through a parsing issue

This topic is 3220 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

what whould be the best way to parse the fallowing file? right now I am trying to use a combination of getline and istringstream
//
[MAP]
{width,height}
{amountoflayers}
//
[Background]
{imagename,maskname}
{width,height}
{x,y}
//
[Background2]
{imagename,maskname}
{width,height}
{x,y}
//
[Playerground]
<Player>
{imagename,maskname}
{width,height}
{x,y}
<enemy1>
{imagename,maskname}
{width,height}
{x,y}
<enemy2>
{imagename,maskname}
{width,height}
{x,y}
<enemy3>
{imagename,maskname}
{width,height}
{x,y}
<NPC1>
{imagename,maskname}
{width,height}
{x,y}
<NPC2>
{imagename,maskname}
{width,height}
{x,y}
<NPC3>
{imagename,maskname}
{width,height}
{x,y}
//
[Forground]
{imagename,maskname}
{width,height}
{x,y}

How I want this to work when it comes to the token [MAP] I want it to fill out the struct for map with data below it then go to the next token and do the same thing. I want lines that begin width // or are empty to be skipped. I am using c/c++

Share this post


Link to post
Share on other sites
Advertisement
Are the tokens like 'width' and 'height' actual tokens, or are they placeholders for the 'real' data? If the latter, can you post an example of what the real file would like?

Share this post


Link to post
Share on other sites
First you need to parse [tokens]
When you encounter a '[', read everything until ']'. That gives you the "type" of what you're going to parse. Then read up to the next '[', that gives you the data to be parsed.

Feed that data into an appropriate sub-parser based on the type.

I think you get the idea.

Also, if you can, change the comment token to be a single char like '#' for example. Having to parse two characters makes it more complicated, maybe for nothing?

I find many languages to be far better suited for text parsing than C++ (python, for example) If possible, use another language to convert (or "pre-process") your text file into something more easily readable from a C++ program.

(Edit: ... or make use C++ as higher level language by using a libriary as suggested below)

[Edited by - janta on April 20, 2009 12:45:04 AM]

Share this post


Link to post
Share on other sites
I've found Boost.Spirit to be useful. It's not too hard to get going with, especially if you can use the default char* iterators. It's worth looking into, anyway.

Share this post


Link to post
Share on other sites
Here is the actule file to be parsed.
It should make a smiple breakout clone game.
once I get it to load then I am going to add collition info into the file



//
[MAP]
//width,height
{ 800 ,600}
//Number of layers
{2}
//
[Background]
{background.bmp,backgroundMask.bmp}
{800,600}
{0,0}
//
[Playerground]
{blocks.bmp,blocksmask.bmp}
//image width and height
{50,30}
//image x and y and tile id
{84,71,1}
{161,83,2}
{84,119,3}
{157,121,4}
//
[PLAYER]
{paddle.bmp,paddlemask.bmp}
//image width and height
{100,50}
//start x and y no need for tile ID
{400,500}
//
[OBJECT1]
{ball.bmp,ballmask.bmp}
//width and height
{40,40}
//start x and y no need for tile ID
{440,540}




Share this post


Link to post
Share on other sites
1) How do you know which objects need a tile ID and which don't?
2) When a tile ID is needed, how do you know how big the tiles are?

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
1) How do you know which objects need a tile ID and which don't?
2) When a tile ID is needed, how do you know how big the tiles are?


1) I only need tile IDs is when I use a single bitmap with multiple tiles in it
2) right now all the tiles are the same size. I have not figured out a way to find collition detection on irregular size tiles

Share this post


Link to post
Share on other sites
Quote:
Original post by kingpinzs
1) I only need tile IDs is when I use a single bitmap with multiple tiles in it


How do you know which bitmaps have multiple tiles in them?

Share this post


Link to post
Share on other sites
does any one have good way to do this in just c++?

Or does any one know any good tutorails for parsing a text file?

[Edited by - kingpinzs on April 26, 2009 12:19:24 PM]

Share this post


Link to post
Share on other sites
How would I use istringstream for this issue?

I can not figure out how to get it to find the [values]
then read in everything tell the next [values].

Is there a way to do that with istringstream or am I going about it the wrong way.

Or should I use something differnt? Like getline or something?

Share this post


Link to post
Share on other sites
All you need to do is use getline() to pull up each line in the file, and then look at the string you're given. If it begins and ends with square brackets, you switch to reading whatever specific data you need from the file.

You should end up with code that works something like this:

Open file
While file is not EOF
Read line from file
Examine which [foo] section you are in
For each line of data needed in the [foo] section:
Read line from file
Construct an istringstream with the line's string value
Read out values using the >> operator on the istringstream



That should be enough to get you going. You don't need to have a really complicated parser for this; remember that the best solution to a problem is usually the simplest solution, unless you have very special circumstances (which, for this scenario, you don't).

Share this post


Link to post
Share on other sites
ApochPiQ thanks for your help. That solustion is exactley what I was looking for. Just one more question. How do I discared a line that I dont want read?

Share this post


Link to post
Share on other sites
Quote:
Original post by kingpinzs
ApochPiQ thanks for your help. That solustion is exactley what I was looking for. Just one more question. How do I discared a line that I dont want read?


You know how you normally process a line you have read? Well, don't do that. Use some kind of conditional statement, or perhaps the "continue" keyword.

Share this post


Link to post
Share on other sites
thanks rip-off I got that to work. trying to put it into a seprate function now becasue I am going to use it alot.

Share this post


Link to post
Share on other sites
well everything is working out so far.
Except I cant read in strings from point a to point b. I got int's to work and chars to work but I cant get strings to work.

this is how I am reading the file

while(!mInputFile.eof())
{
getline(mInputFile,s);
instream.clear();
instream.str(s);

if(s.substr(0,1) !="#" || !s.empty())
{
if(s == "[MAP]")
{
while(s.substr(0,1) !=";")
{
getline(mInputFile,s);//gets next line
instream.str(s);//sets to next line

if(SkipLine(s) && instream>>op>>a>>op>>b>>op)
{
cout<<a<<" "<<b<<endl;
}
if(SkipLine(s)&& instream>>op>>c>>op)
{
cout<<c<<endl;
}
}

}

//here is the issue
if(s == "[Background]")
{
while(s.substr(0,1) !=";")
{
getline(mInputFile,s);//gets next line
instream.str(s);//sets to next line

//right here I am trying to start reading at { and stop reading at ,that will
//be the first string then continue reading from , to }

if(SkipLine(s)&&instream>>cur>>test>>sep>>nam>>curend)
{
cout<<test<<" "<<nam<<endl;
}
/*
if(SkipLine(inner)&&
{800,600}
if(SkipLine(inner)&&
{0,0}*/


}
}
}




any one know how I could start reading at { and stop reading at , on the same line?

Share this post


Link to post
Share on other sites
Search for a '{'
Then read every character that isn't a '.' or a new line.

It's as easy or as difficult as you want. istream::get and istream::peek are pretty much everything you need. All the rest is optimisation really.

Share this post


Link to post
Share on other sites
Quote:
Original post by Kylotan
Search for a '{'
Then read every character that isn't a '.' or a new line.

It's as easy or as difficult as you want. istream::get and istream::peek are pretty much everything you need. All the rest is optimisation really.


could you show me an example how you would read
{800,5}
{2,50,54}

using istream::get and istream::peek?

Thanks

Share this post


Link to post
Share on other sites
I think you can probably do this yourself, if you put a little thought into it.

You have a string of the form {xxx,yyy}. You want to verify that it begins with a { and ends with a } (which you can do using std::string's member functions easily). Then you want to extract the substring between the { and the , which again can be done easily with std::string. Then you want to extract the substring between the , and the } using a similar method.

Finally, you want to convert the xxx and yyy substrings into numeric format, which you can do yourself using an istringstream or using something like boost::lexical_cast.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement