Parsing Files

Started by
5 comments, last by Zorbfish 21 years, 1 month ago
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;
			}

		}
}
}
  
Advertisement
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?
??? 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
}
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

  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 ).
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
S''right. Have fun d00d

This topic is closed to new replies.

Advertisement