reading para values from config file with type

C

cuneyt

Hi

I am working on a class that reads parameter values from a
configuration file
and inserts them into a hash. There are many good dimplementations of
this on
the Web. What I would like to do, however, is to automatically
determine the
type (int, double, or bool) of each value (similar to what MATLAB does)
and
insert them accordingly.

For example, if the config file has
VAL1 150
VAL2 0.005
I would like my hash to have one int and one double value,
rather than two strings

The current Read function below reads all pairs as strings. Problem
with this is
that each time I want to use the values in my program, I have to cast
them.

With my funstion template knowledge I was unable to write the code to
do this.
I would very much appreciate any help.

Thanks,

Cuneyt



class CSysConfig {
friend std::eek:stream & operator<<( std::eek:stream &lhs, const
CSysConfig &rhs );

private:
std::map<std::string,std::string> m_params; ///<
configuration parameters
std::string m_commentStartStr; ///< string
that marks a line as a comment
std::ifstream m_fileStream; ///< input stream
for config file

public:
CSysConfig();
virtual ~CSysConfig() {};

initialize( char* configFileName );
initialize( char* configFileName, std::string str );
int CSysConfig::isInitalized();
int CSysConfig::read( char* readType );
std::string getParamVal( std::string key );
};


///////////////////////////////////////////////////////////////////////////////
/// Reads all key,value pairs from given stream into hash data member.
///////////////////////////////////////////////////////////////////////////////
int CSysConfig::read( char* readType )
{
std::vector<std::string> line;
int nLine = 0, nTokens;

if( ! this->isInitalized() ) {
std::cerr << "read method called for uninitialized CSysConfig
object!" << std::endl;
return SYSCONFIG_READ_ERROR;
}

bool infer;
if( strcmp(readType,"all_string") == 0 ) {
infer = false;
}
else if ( strcmp(readType,"infer_types") == 0 ) {
infer = true;
}
else {
std::cerr << "Unknown read type (" << readType << ") in
CSysConfig::read!" << std::endl;
return SYSCONFIG_READ_ERROR;
}

while( !m_fileStream.eof() ) {
nLine++;
nTokens = getNextTokenizedLine( m_fileStream, line );
if( m_fileStream.eof() ) { break; }
if( nTokens > 0 ) { // line is not empty
// If the substring m_commentStartStr is found the first token
// starting from position 0, line is a comment.
if( line[0].find( m_commentStartStr,0 ) != 0 ) {
// line is not a comment
if( nTokens != 2 ) {
std::cout << "syntax error in line " << nLine << ", more than two
tokens in noncomment line! " << std::endl;
return SYSCONFIG_READ_ERROR;
}
else {
if( infer ) {
/* DETERMINING THE TYPE OF EACH PARAMETER VALUE
AND
INSERT IT TO THE HASH ACCORDINGLY */
}
else {
if( m_params.find( line[0] ) != m_params.end() ) {
std::cout << "repeated key (" << line[0] << ") in line " <<
nLine << std::endl;
return SYSCONFIG_READ_ERROR;
}
m_params[line[0]] = line[1];
}
}
}
else { // line is a comment, do nothing.
}
}
}
return SYSCONFIG_OK;
}
 
G

guyarad

With the assumption that you know how to seperate the two strings you
can do the following:
Value seperation:
if the number consist of numbers and a dot
it is float (or double)
else if the number consist only number
it is an int
else if the number (as string) equal 'true' or 'false'
it is bool, and assign the appropriate value

Once you have that the question is what do you want to do with this
information? how do you want to store?
 
P

peter steiner

cuneyt said:
Hi

I am working on a class that reads parameter values from a
configuration file
and inserts them into a hash. There are many good dimplementations of
this on
the Web. What I would like to do, however, is to automatically
determine the
type (int, double, or bool) of each value (similar to what MATLAB does)
and
insert them accordingly.

you can try to parse the value string and look for a full match. this
works because floating point numbers always include at least a trailing
dot that is not parsed if istream reads the preceding integer value.
this way you can also read scientific notation, hex, etc...

enum Type { TBool, TDouble, TLong, TInvalid };

Type parse(string val, bool& b, double& d, long& l)
{
// manually check for bool
if (val == "true") {
b = true;
return TBool;
}
else if (val == "false") {
b = false;
return TBool;
}

// check for long
istringstream in(str);
if (in >> l && in.eof())
return TLong;

// check for double
in.str(str);
if (in >> d && in.eof())
return TDouble;

return TInvalid;
}

-- peter
 
P

peter steiner

btw, you may also want to use a variant container like boost::variant
to be able to store the different types in a single container and
access them in a safe way.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top