使用C++拆分"[General Setting]"格式的部分字符串

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

本文关键字:格式 字符串 Setting C++ 拆分 General 使用      更新时间:2023-10-16

我是C++新手,我想读取具有部分和键值对的ini文件。根据该部分,我想读取相应键的值。首先,我想阅读括在方括号中的部分。请帮忙。谢谢。

对于真正的INI文件解析,我强烈建议使用iniparser库。它有很好的文档记录,并且在 C C++ 程序中都易于使用。

如果您只对解析 [Section name] 形式的字符串感兴趣,您可以执行以下操作:找到字符串的第一个"["和最后一个"]"并标记位置。如果找到这两个字符,请将节名称作为您标识的位置之间的子字符串。

假设您使用的是 std::string ,您可以执行以下操作:

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;

此代码段应向您展示解析 ini 文件和跳过 # 或 ; 被视为注释的前缀行

这需要对组名、名称和值进行健全性检查,但应该足以作为演示:

#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 = "rn tba";
        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;
}