Archived

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

Zorbfish

Parsing Files

Recommended Posts

Zorbfish    214
I wrote this up quick just to see how I would have to parse my data. Now I''m trying to clean up this code and make it much more managed. What would you suggest??? Right now I was thinking about creating a class with database-like behavior that holds all the known params of each type. Then I could just pass the type name and load accordingly.
  
void Map::Load(string file)
{
	
	ifstream	input;
	string		type_name, param_name, eat;
	int		room_id;
	int		exit_ids[4];
	string		room_name;
	string		room_description;
	string		exit_names[4];
	Room		new_room;


	input.open(file.c_str());

	if(input.fail())
		cout << "No file";
	else
	{
		input >> type_name;

		while(!input.eof() && !input.fail())
		{

		///////////////////////////////////////////////

		// type - ROOM

		///////////////////////////////////////////////

			if(type_name == "room")
			{
				input >> eat;	// eat bracket

				input >> param_name;

				while(param_name != "}")
				{
					/////////////////////////////////////

					// param - ID

					/////////////////////////////////////

					if(param_name == "id")
					{
						input >> eat;
						input >> room_id;
					}
					/////////////////////////////////////

					// param - NAME

					/////////////////////////////////////

					if(param_name == "name")
					{
						input >> eat;
						input.ignore(1);
						getline(input, room_name, ''\n'');
					}
					/////////////////////////////////////

					// param - DESCRIPTION

					/////////////////////////////////////

					if(param_name == "description")
					{
						input >> eat;
						input.ignore(1);
						getline(input, room_description, ''\n'');
					}
					/////////////////////////////////////

					// param - NORTH

					/////////////////////////////////////

					if(param_name == "north")
					{
						input >> eat;
						input.ignore(1);
						getline(input, exit_names[North], '','');
						input >> exit_ids[North];
					}
					/////////////////////////////////////

					// param - SOUTH

					/////////////////////////////////////

					if(param_name == "south")
					{
						input >> eat;
						input.ignore(1);
						getline(input, exit_names[South], '','');
						input >> exit_ids[South];
					}
					
					input >> param_name;
				}

				input >> type_name;
			}

		}
}
}
  

Share this post


Link to post
Share on other sites
YodaTheCoda    100
this is realy very simple
all yuo must do is to read in tyhe file and pass the apropriet parameters to the variebls. it is genrally known as file io
just practise a bit and yuo wil get the hang of it?

Share this post


Link to post
Share on other sites
Zorbfish    214
??? I know its file io, what I was asking is there a way to design my code to make it more organized as in its current state, IMO, its rather disorganized. :/

btw here''s a sample of how I setup my file

room
{
id = 1
name = House1
description = You entered a small house you catch a glance at an old man rocking in a chair
north = Stairs, 2
south = Outside, 3
}

Share this post


Link to post
Share on other sites
AdmiralBinary    100
Simplest way is using the STL map class.

  
class Object
{
public:
void Load(ifstream & file);
map<string,string> mData;
};

void Object::Load(ifstream & file)
{
while (!file.eof())
{
char tmp[256];
file.getline(tmp,255);
string str = tmp;
if (str.empty())
continue;
else
{
//break up the string here into words - ask if u need help with this

mData[word1] = word2;
}
}
}

This is a pretty simple (read incomplete) example, but I''ve found this method to be by far the most flexible in file I/O (especially for text-based games).

Hope it helps

Share this post


Link to post
Share on other sites
AdmiralBinary    100

  
vector<string> Breakup(string str, char sep)
{
vector<string> ret;
if (str.empty())
return ret;

string word = "";
bool quote = false;

for (int i = 0; i < str.length(); ++i)
{
if (str[i] == ''"
'')
quote = !quote;
if (str[i] == sep && !quote)
{
if (!word.empty()) ret.push_back(word);
word = "";
} else
{
word += str[i];
}
}

if (!word.empty())
ret.push_back(word);

return ret;
}

class Object
{
public:
void Load(ifstream & file);
map<string,string> mData;
};

void Object::Load(ifstream & file)
{
while (!file.eof())
{
char tmp[256];
file.getline(tmp,255);
string str = tmp;
if (str.empty())
continue;
else if (str == "
{")
continue;
else if (str == "
}")
break;
else
{
vector<string> word = Breakup(str,'' '');
mData[word[0]] = word[2]; //word[1] is the = sign

}
}
}

class World
{
public:
void Load(ifstream & file);
list<Object> lObjects;
};

void World::Load(ifstream & file)
{
while (!file.eof())
{
char tmp[256];
file.getline(tmp,255);
string str = tmp;
if (str.empty())
continue;
else if (str == "
object")
{
Object o;
o.Load(file);
lObjects.push_back(o);
}
}
}

Slightly more complete example - let me know if u don''t understand anything (very likely considering the way I code ).

Share this post


Link to post
Share on other sites
Zorbfish    214
I see, thanks admiral that''s a great design. And just to clarify because I haven''t used maps that much.

mData[word[0]] = word[2]; //word[1] is the = sign

This is essentially telling the map to lookup the param stored in it and assign the value, correct? Where the string was broken into 3 pieces:

0 - Parameter name
1 - seperator
2 - Value

Share this post


Link to post
Share on other sites