reading para values from config file with type

Discussion in 'C++' started by cuneyt, Dec 14, 2005.

  1. cuneyt

    cuneyt Guest

    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;
    }
     
    cuneyt, Dec 14, 2005
    #1
    1. Advertising

  2. cuneyt

    Guest

    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?
     
    , Dec 14, 2005
    #2
    1. Advertising

  3. cuneyt wrote:
    > 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
     
    peter steiner, Dec 14, 2005
    #3
  4. 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.
     
    peter steiner, Dec 14, 2005
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Sergio Alvarez

    Ayuda para java

    Sergio Alvarez, Jan 21, 2006, in forum: Java
    Replies:
    4
    Views:
    2,405
    Mike Schilling
    Jan 22, 2006
  2. mvogel

    apoyo para el tema xml

    mvogel, May 12, 2005, in forum: XML
    Replies:
    0
    Views:
    464
    mvogel
    May 12, 2005
  3. Sedney
    Replies:
    1
    Views:
    572
    Aggro
    Jul 24, 2003
  4. nospam
    Replies:
    14
    Views:
    526
    Barry Schwarz
    Feb 4, 2007
  5. kampy
    Replies:
    9
    Views:
    371
    Steven D'Aprano
    Oct 19, 2012
Loading...

Share This Page