C + + class to read configuration file Config prepared

Foreigner to write a piece of code to write in the Server reads the configuration file of this class more practical

//Config.h
#pragma once

#include <string>
#include <map>
#include <iostream>
#include <fstream>
#include <sstream>

/*
* \brief Generic configuration Class
*
*/
class Config {
        // Data
protected:
        std::string m_Delimiter;  //!< separator between key and value
        std::string m_Comment;    //!< separator between value and comments
        std::map<std::string,std::string> m_Contents;  //!< extracted keys and values

        typedef std::map<std::string,std::string>::iterator mapi;
        typedef std::map<std::string,std::string>::const_iterator mapci;
        // Methods
public:

        Config( std::string filename,std::string delimiter = "=",std::string comment = "#" );
        Config();
        template<class T> T Read( const std::string& in_key ) const;  //!<Search for key and read value or optional default value, call as read<T>
        template<class T> T Read( const std::string& in_key, const T& in_value ) const;
        template<class T> bool ReadInto( T& out_var, const std::string& in_key ) const;
        template<class T>
        bool ReadInto( T& out_var, const std::string& in_key, const T& in_value ) const;
        bool FileExist(std::string filename);
        void ReadFile(std::string filename,std::string delimiter = "=",std::string comment = "#" );

        // Check whether key exists in configuration
        bool KeyExists( const std::string& in_key ) const;

        // Modify keys and values
        template<class T> void Add( const std::string& in_key, const T& in_value );
        void Remove( const std::string& in_key );

        // Check or change configuration syntax
        std::string GetDelimiter() const { return m_Delimiter; }
        std::string GetComment() const { return m_Comment; }
        std::string SetDelimiter( const std::string& in_s )
        { std::string old = m_Delimiter;  m_Delimiter = in_s;  return old; }
        std::string SetComment( const std::string& in_s )
        { std::string old = m_Comment;  m_Comment =  in_s;  return old; }

        // Write or read configuration
        friend std::ostream& operator<<( std::ostream& os, const Config& cf );
        friend std::istream& operator>>( std::istream& is, Config& cf );

protected:
        template<class T> static std::string T_as_string( const T& t );
        template<class T> static T string_as_T( const std::string& s );
        static void Trim( std::string& inout_s );

        // Exception types
public:
        struct File_not_found {
                std::string filename;
                File_not_found( const std::string& filename_ = std::string() )
                        : filename(filename_) {} };
                struct Key_not_found {  // thrown only by T read(key) variant of read()
                        std::string key;
                        Key_not_found( const std::string& key_ = std::string() )
                                : key(key_) {} };
};

/* static */
template<class T>
std::string Config::T_as_string( const T& t )
{
        // Convert from a T to a string
        // Type T must support << operator
        std::ostringstream ost;
        ost << t;
        return ost.str();
}

/* static */
template<class T>
T Config::string_as_T( const std::string& s )
{
        // Convert from a string to a T
        // Type T must support >> operator
        T t;
        std::istringstream ist(s);
        ist >> t;
        return t;
}

/* static */
template<>
inline std::string Config::string_as_T<std::string>( const std::string& s )
{
        // Convert from a string to a string
        // In other words, do nothing
        return s;
}

/* static */
template<>
inline bool Config::string_as_T<bool>( const std::string& s )
{
        // Convert from a string to a bool
        // Interpret "false", "F", "no", "n", "0" as false
        // Interpret "true", "T", "yes", "y", "1", "-1", or anything else as true
        bool b = true;
        std::string sup = s;
        for( std::string::iterator p = sup.begin(); p != sup.end(); ++p )
                *p = toupper(*p);  // make string all caps
        if( sup==std::string("FALSE") || sup==std::string("F") ||
                sup==std::string("NO") || sup==std::string("N") ||
                sup==std::string("0") || sup==std::string("NONE") )
                b = false;
        return b;
}

template<class T>
T Config::Read( const std::string& key ) const
{
        // Read the value corresponding to key
        mapci p = m_Contents.find(key);
        if( p == m_Contents.end() ) throw Key_not_found(key);
        return string_as_T<T>( p->second );
}

template<class T>
T Config::Read( const std::string& key, const T& value ) const
{
        // Return the value corresponding to key or given default value
        // if key is not found
        mapci p = m_Contents.find(key);
        if( p == m_Contents.end() ) return value;
        return string_as_T<T>( p->second );
}

template<class T>
bool Config::ReadInto( T& var, const std::string& key ) const
{
        // Get the value corresponding to key and store in var
        // Return true if key is found
        // Otherwise leave var untouched
        mapci p = m_Contents.find(key);
        bool found = ( p != m_Contents.end() );
        if( found ) var = string_as_T<T>( p->second );
        return found;
}

template<class T>
bool Config::ReadInto( T& var, const std::string& key, const T& value ) const
{
        // Get the value corresponding to key and store in var
        // Return true if key is found
        // Otherwise set var to given default
        mapci p = m_Contents.find(key);
        bool found = ( p != m_Contents.end() );
        if( found )
                var = string_as_T<T>( p->second );
        else
                var = value;
        return found;
}

template<class T>
void Config::Add( const std::string& in_key, const T& value )
{
        // Add a key with given value
        std::string v = T_as_string( value );
        std::string key=in_key;
        trim(key);
        trim(v);
        m_Contents[key] = v;
        return;
}
// Config.cpp

#include "Config.h"

using namespace std;

Config::Config( string filename, string delimiter,
                           string comment )
                           : m_Delimiter(delimiter), m_Comment(comment)
{
        // Construct a Config, getting keys and values from given file

        std::ifstream in( filename.c_str() );

        if( !in ) throw File_not_found( filename ); 

        in >> (*this);
}

Config::Config()
: m_Delimiter( string(1,'=') ), m_Comment( string(1,'#') )
{
        // Construct a Config without a file; empty
}

bool Config::KeyExists( const string& key ) const
{
        // Indicate whether key is found
        mapci p = m_Contents.find( key );
        return ( p != m_Contents.end() );
}

/* static */
void Config::Trim( string& inout_s )
{
        // Remove leading and trailing whitespace
        static const char whitespace[] = " \n\t\v\r\f";
        inout_s.erase( 0, inout_s.find_first_not_of(whitespace) );
        inout_s.erase( inout_s.find_last_not_of(whitespace) + 1U );
}

std::ostream& operator<<( std::ostream& os, const Config& cf )
{
        // Save a Config to os
        for( Config::mapci p = cf.m_Contents.begin();
                p != cf.m_Contents.end();
                ++p )
        {
                os << p->first << " " << cf.m_Delimiter << " ";
                os << p->second << std::endl;
        }
        return os;
}

void Config::Remove( const string& key )
{
        // Remove key and its value
        m_Contents.erase( m_Contents.find( key ) );
        return;
}

std::istream& operator>>( std::istream& is, Config& cf )
{
        // Load a Config from is
        // Read in keys and values, keeping internal whitespace
        typedef string::size_type pos;
        const string& delim  = cf.m_Delimiter;  // separator
        const string& comm   = cf.m_Comment;    // comment
        const pos skip = delim.length();        // length of separator

        string nextline = "";  // might need to read ahead to see where value ends

        while( is || nextline.length() > 0 )
        {
                // Read an entire line at a time
                string line;
                if( nextline.length() > 0 )
                {
                        line = nextline;  // we read ahead; use it now
                        nextline = "";
                }
                else
                {
                        std::getline( is, line );
                }

                // Ignore comments
                line = line.substr( 0, line.find(comm) );

                // Parse the line if it contains a delimiter
                pos delimPos = line.find( delim );
                if( delimPos < string::npos )
                {
                        // Extract the key
                        string key = line.substr( 0, delimPos );
                        line.replace( 0, delimPos+skip, "" );

                        // See if value continues on the next line
                        // Stop at blank line, next line with a key, end of stream,
                        // or end of file sentry
                        bool terminate = false;
                        while( !terminate && is )
                        {
                                std::getline( is, nextline );
                                terminate = true;

                                string nlcopy = nextline;
                                Config::Trim(nlcopy);
                                if( nlcopy == "" ) continue;

                                nextline = nextline.substr( 0, nextline.find(comm) );
                                if( nextline.find(delim) != string::npos )
                                        continue;

                                nlcopy = nextline;
                                Config::Trim(nlcopy);
                                if( nlcopy != "" ) line += "\n";
                                line += nextline;
                                terminate = false;
                        }

                        // Store key and value
                        Config::Trim(key);
                        Config::Trim(line);
                        cf.m_Contents[key] = line;  // overwrites if key is repeated
                }
        }

        return is;
}
bool Config::FileExist(std::string filename)
{
        bool exist= false;
        std::ifstream in( filename.c_str() );
        if( in )
                exist = true;
        return exist;
}

void Config::ReadFile( string filename, string delimiter,
                                          string comment )
{
        m_Delimiter = delimiter;
        m_Comment = comment;
        std::ifstream in( filename.c_str() );

        if( !in ) throw File_not_found( filename ); 

        in >> (*this);
}
//main.cpp
#include "Config.h"
int main()
{
        int port;
        std::string ipAddress;
        std::string username;
        std::string password;
        const char ConfigFile[]= "config.txt";
        Config configSettings(ConfigFile);

        port = configSettings.Read("port", 0);
        ipAddress = configSettings.Read("ipAddress", ipAddress);
        username = configSettings.Read("username", username);
        password = configSettings.Read("password", password);
        std::cout<<"port:"<<port<<std::endl;
        std::cout<<"ipAddress:"<<ipAddress<<std::endl;
        std::cout<<"username:"<<username<<std::endl;
        std::cout<<"password:"<<password<<std::endl;

        return 0;
}

contents of the file config.txt:
ipAddress = 10.10.90.125
port = 3001
username = mark
password = 2d2df5a

Compile and run the output:
port: 3001
ipAddress: 10.10.90.125
username: mark
password: 2d2df5a

This class there are many other ways, you can call to try.

分类:CPP 时间:2010-10-05 人气:210
分享到:
blog comments powered by Disqus

相关文章

  • [Change] Spring transaction configuration Five Ways 2010-03-29

    Some time ago to the Spring transaction configuration done a more in-depth research in this matter between the configuration of the Spring is also configured though, but it has not been a clear understanding. Through this study found that Spring's tr

  • [Change] WebSphere Common Configuration 2010-03-09

    WebSphere configuration commonly used in Chinese garbage problem 1. In the top of each jsp file, add the following two lines: <% @ Page c%> <% request.setCharacterEncoding ( "GBK ");%> 2. In the console, select Server> Java and Pr

  • Spring configuration used in proxool + [change] proxool.xml configuration properties description 2008-10-31

    1. Configuration proxool.xml Add proxool.xml file to the project's / WEB-INF under. Connect to the database Oracle configuration is as follows: <! - <br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware) <br />

  • Howto: change andLinux network configuration 2010-03-04

    Contents [ Hide ] 1 Abstract 2 What needs to be changed? 3 Step-by-step 3.1 andLinux eth1 ip address configuration 3.2 andLinux / etc / hosts file 3.3 andLinux / etc / profile configuration 3.4 TAP-Colinux ip address configuration 3.5 andLinux launch

  • [Change] tnsnames.ora Configuration Summary 2010-04-23

    listener.ora, sqlnet.ora, tnsnames.ora, are placed in $ ORACLE_HOME \ network \ admin directory. Focus: the role of the three documents and the use of #----------------------- sqlnet.ora----- effect similar to linux or other unix's nsswitch.conf file

  • [Change] Spring transaction configuration of five ways 2010-06-13

    Spring transaction configuration of five ways (http://www.blogjava.net/robbie/archive/2009/04/05/264003.html) Spring's transaction configuration while ago on doing more in-depth study, in which the transaction between the configuration of the Spring

  • [Change] android avd configuration error solution 2010-08-27

    Today, companies require a school to go to the room configuration android development environment, in front of work, what adt the installation has gone smoothly; the next time configuration avd have a problem, and with good avd, new android project,

  • log4j configuration instructions 2010-05-07

    Java programming using specific Log4j can refer to the following example: 1, the establishment of Logger instance: Syntax said: public static Logger getLogger (String name) Actual use: static Logger logger = Logger.getLogger (ServerWithLog4j.class.ge

  • [Change] log4j configuration Xiangjie 2010-06-08

    >>>> 1. Overview Introduction Log4j development of reusable components in the stress of today, in addition to its own from start to finish development of a reusable logging operations outside class, Apache provides us with a powerful logging o

iOS 开发

Android 开发

Python 开发

JAVA 开发

开发语言

PHP 开发

Ruby 开发

搜索

前端开发

数据库

开发工具

开放平台

Javascript 开发

.NET 开发

云计算

服务器

Copyright (C) codeweblog.com, All Rights Reserved.

CodeWeblog.com 版权所有 黔ICP备15002463号-1

processed in 0.278 (s). 12 q(s)