parsing a text file

Started by
4 comments, last by McZ 20 years ago
I''m trying to create a SettingsManager where I can register a type of setting and what IDTag it has in the config file and a default value e.g.


int MyValue; // this is the value read from my config file


/*
first all stuff needs to register what stuff they want to have in the settings file
*/
cSettingsManager::Create()->Register( "MYVALUE", &MyValue, 10 );
...

/*
when all things that wants to have something from the config file has register ther Settings values we can read the file. which is plane text
*/
cSettingsManager::Create()->LoadConfig( "Config.cfg" );

/*
becouse I register all Values first I can create a new config file from the registerd values and there current/default value.
*/
cSettingsManager::Create()->SaveConfig( "newConfig.cfg" );
well... the problem is when I parse a file it works perfect when there is no whitespaces on the line to parse if the config looks like this it works MYVALUE=555 but if it looks like this it doesn''t work MYVALUE = 555 is there a way to remove white spaces from a line?
Advertisement
If you are using C++, you can use std::cin >> x; if(x == "some_token") std::cin >> some_value; and whitespace will* be eaten.

*or should.
yes I''m using C++ but I can''t understand how "std::cin >> x; if(x == "some_token") std::cin >> some_value;" will help me with reading a file and remove whitespace characters.
std::cin does this thing called "tokenization" on your input. If for example you try to read in a string value with the overloaded ''shift'' operator, it will skip leading whitespace, and read in text until the next whitespace.

So in your example, you would read in a string, check that it matches "MYVALUE"; read in another string, make sure it matches "=", and then conclude that you need to read in an int and interpret it as MYVALUE. Of course, now you need to handle the case when the spaces *aren''t* there

This is really the sort of thing that is better done with higher-level languages/tools. Try researching "bindings" for Python (or other scripting languages - I''m a Perl h4><0r, personally) to C++. Alternatively, see if you can find a good "regular expression" library for C++.
quote:Of course, now you need to handle the case when the spaces *aren''t* there


Read the whole line with std::getline into a std::string

Use std::string::find on the ''='' to get an index

You can then std::string::substr the two parts into the ''key'' and the ''value''

If it is a numerical value, create a std::istringstream from the value string and then use the extaction operator to put this into a variable (of the appropriate type).

  string file_line ("VALUE = 100";  string key = file_line.substr (0, file_line.find (''=''));  string val = file_line.substr (file_line.find (''='')+1);  key = key.erase (val.find_last_not_of ('' '')+1);     istringstream iss (val);  int v;  iss >> v; 


The find_last_not_of bit is so you can strip the trailing whitespace but still keep multi-string keys e.g. "MY VALUE"

Also, you can check the return of ''find'' to check it is a valid line with ''='', the state of iss to ensure a suitable value was read, the first character of file_line to see if it is a comment ... blah blah error check blah

>>> key = key.erase (val.find_last_not_of ('' '')+1);

key = key.erase (key.find_last_not_of ('' '')+1);

This topic is closed to new replies.

Advertisement