2012-06-06 1 views
3

저는 C++을 처음 사용하기 때문에 섹션과 키 - 값 쌍이있는 ini 파일을 읽고 싶습니다. 섹션에 따라 해당 키의 값을 읽고 싶습니다. 주로 대괄호로 묶인 섹션을 읽고 싶습니다. 도와주세요. 감사합니다."[일반 설정]"형식의 섹션 문자열을 분할하는 C++ 사용

+0

당신은 문자열 형식의 예를 제공 할 수 있습니다. –

답변

2

실제 INI 파일 구문 분석을 위해 iniparser library을 제안합니다. C C++ 프로그램 모두에서 문서화되고 사용하기 쉽습니다.

[Section name] 형식의 문자열을 구문 분석하는 데 관심이있는 경우 다음을 수행 할 수 있습니다. 문자열에 대해 '['및 last ']를 찾아 위치를 표시하십시오. 두 문자가 모두 발견되면 섹션 이름을 사용하여 식별 한 위치 사이에서 하위 문자열이되도록합니다. 당신이 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; 
+2

멋진 라이브러리, 이제 RAII의 장점과 강력한 타이핑을 위해 C++ 래퍼가 필요합니다. :) –

+0

@MatthieuM. +1 너무 무언가를 위해. 나는 과거의 몇몇 프로젝트에서이 프로젝트를 사용 해왔고 적어도 어떤 종류의 래퍼 기능을 항상 썼다. – Gnosophilon

0

당신에게 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 = "\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; 
} 
관련 문제