简体   繁体   中英

Using C++ splitting a section string which is in “[General Setting]” format

I am new to C++, i want to read ini file which has section and key - value pair. Depending on the section, i want to read the value for corresponding key. Primarily, i want to read the section which is enclosed in square brackets. Please help. Thank you.

For real INI file parsing, I highly suggest the iniparser library . It is excellently documented and easy to use in both C and C++ programs.

If you are only interested in parsing strings of the form [Section name] , you could do the following: Find first '[' and last ']' for the string and mark the positions. If both characters have been found, take the section name to be substring between the positions you identified.

Assuming you are using an std::string , you can do the following:

std::string myString = " [Section name] ";

std::size_t start = myString.find_first_of( '[' );
std::size_t end   = myString.find_last_of( ']' );

std::string sectionName;
if( start != std::string::npos && end != std::string::npos )
{
  sectionName = myString.substr(start + 1, end - 1);
}

std::cout << sectionName << std::endl;

This snippet should show you the basic logic for parsing an ini file and skipping # or ; prefixed lines which are treated as comments

this needs sanity checks for group names, names and values, but should suffice as a demonstration:

#include <iostream>
#include <string>
#include <map>
//
//   a simple ini file parser (doesn't check for validity of name field length wise or if it has = char
//   to demonstrate basic parsing
//
class IniFile
{
public:
    enum { MAX_LINE_LEN = 10*1024 };
    class MalformedInputException : public std::exception
    {
    public:
        const char* what() const throw() { return "Input is not a valid or well formed ini file"; }
    };
    typedef std::map<std::string, std::string> Properties;
    IniFile(){}
    virtual ~IniFile(){}

    std::istream& load(std::istream& in)
    {
        char lineBuffer[MAX_LINE_LEN];
        std::string curGroup = "";
        while(!in.eof())
        {
            in.getline(lineBuffer, MAX_LINE_LEN);
            //std::cout<<"line buffer : {"<<lineBuffer<<"}"<<std::endl;
            std::string line = trim(lineBuffer);
            //std::cout<<"trimmed : {"<<line<<"}"<<std::endl;
            // we process only non-empty / non-comment lines
            if(line.size() > 0 && line[0] != '#' && line[0] != ';')
            {
                if(line[0] == '[' && line[line.size() - 1] == ']')
                {
                    curGroup = trim(line.substr(1, line.size() - 2));
                }
                else if(curGroup.size() > 0)
                {
                    size_t index = line.find_first_of('=');
                    //todo: needs checks for valid name=value format here
                    Properties& props = m_props[curGroup]; // this will create new Properties if none exists
                    props[line.substr(0,index)] = line.substr(index+1);
                }
                else
                {
                    throw MalformedInputException();
                }

            }
        }
        return in;
    }
    std::ostream& save(std::ostream& os) const
    {
        std::map<std::string, Properties>::const_iterator iter = m_props.begin();
        while(iter != m_props.end())
        {
            os<<"["<<iter->first<<"]"<<std::endl;
            Properties::const_iterator propIter = iter->second.begin();
            while(propIter != iter->second.end())
            {
                os<<propIter->first<<"="<<propIter->second<<std::endl;
                propIter++;
            }
            iter++;
        }
        return os;
    }
    std::string trim(const std::string& input)
    {
        static std::string WHITESPACES = "\r\n \t\b\a";
        if(input.size() == 0){ return input; }
        else
        {
            size_t start = 0;

            for(size_t index = 0; index < input.size(); index++)
            {
                if(WHITESPACES.find(input[index]) < WHITESPACES.size())
                {
                    start = index;
                }
                else
                {
                    break;
                }
            }
            size_t endIndex = input.size() - 1;
            if(start == endIndex){ return ""; }
            for(; endIndex > start; endIndex--)
            {
                char c = input.at(endIndex);
                if(WHITESPACES.find_first_of(c) >= WHITESPACES.size())
                {
                    break;
                }
            }
            size_t length = endIndex - start + 1;
            return input.substr(start, length);
        }
    }
private:
    std::map<std::string, Properties> m_props;
};


inline std::ostream& operator << (std::ostream& os, const IniFile& iniFile)
{
    return iniFile.save(os);
}
inline std::istream& operator >> (std::istream& in, IniFile& iniFile)
{
    return iniFile.load(in);
}
#include <sstream>
int main(int argc, char** argv)
{
    std::ostringstream ss;
    ss<<"# sample ini file"<<std::endl;
    ss<<"[Group1]"<<std::endl;
    ss<<"foo=bar    \n"<<std::endl;
    ss<<"baz=foz"<<std::endl;
    ss<<"; this is another comment"<<std::endl;
    ss<<"[Group2]"<<std::endl;
    ss<<"blanga=kukoo"<<std::endl;

    std::string buf = ss.str();
    std::istringstream sin(buf);

    IniFile iniFile;
    iniFile.load(sin);

    iniFile.save(std::cout<<"Ini File Loaded : "<<std::endl);
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM