IT story

C ++에서 INI 파일을 구문 분석하는 가장 쉬운 방법은 무엇입니까?

hot-time 2020. 9. 12. 11:35
반응형

C ++에서 INI 파일을 구문 분석하는 가장 쉬운 방법은 무엇입니까?


C ++를 사용하여 INI 파일을 구문 분석하려고합니다. 이를 달성하는 가장 좋은 방법은 무엇입니까? INI 파일 처리 (완전히 익숙하지 않은), 오픈 소스 솔루션에 Windows API 도구를 사용해야합니까? 아니면 수동으로 구문 분석을 시도해야합니까?


GetPrivateProfileString ()GetPrivateProfileInt ()같은 Windows API 함수를 사용할 수 있습니다 .


크로스 플랫폼 솔루션이 필요한 경우 Boost의 프로그램 옵션 라이브러리를 사용해보십시오 .


ini 파일을 구문 분석 한 적이 없으므로이 문제에 대해 너무 구체적으로 말할 수 없습니다.
하지만 한 가지 조언이 있습니다. 기존 제품이 요구 사항을 충족하는 한 바퀴를 재발 명하지 마십시오 .

http://en.wikipedia.org/wiki/INI_file#Accessing_INI_files
http://sdl-cfg.sourceforge.net/
http://sourceforge.net/projects/libini/
http://www.codeproject.com/KB /files/config-file-parser.aspx

행운을 빕니다 :)


나는 SimpleIni를 사용한다 . 크로스 플랫폼입니다.


이미 Qt를 사용하고있는 경우

QSettings my_settings("filename.ini", QSettings::IniFormat);

그런 다음 값을 읽습니다.

my_settings.value("GroupName/ValueName", <<DEFAULT_VAL>>).toInt()

INI 값을 표준 유형과 Qt 유형으로 변환하는 다른 변환기가 많이 있습니다. 자세한 내용은 QSettings에 대한 Qt 설명서를 참조하십시오.


이 질문은 약간 오래되었지만 내 답변을 게시하겠습니다. 다양한 INI 클래스를 테스트했습니다 (내 웹 사이트 에서 볼 수 있음 ). Windows와 winCE 모두에서 INI 파일로 작업하기를 원하기 때문에 simpleIni도 사용합니다. Window의 GetPrivateProfileString ()은 winCE의 레지스트리에서만 작동합니다.

simpleIni로 읽기가 매우 쉽습니다. 다음은 예입니다.

#include "SimpleIni\SimpleIni.h"    
CSimpleIniA ini;
ini.SetUnicode();
ini.LoadFile(FileName);
const char * pVal = ini.GetValue(section, entry, DefaultStr);

inih 는 C로 작성된 간단한 ini 파서이며 C ++ 래퍼도 함께 제공됩니다. 사용 예 :

#include "INIReader.h"    

INIReader reader("test.ini");

std::cout << "version="
          << reader.GetInteger("protocol", "version", -1) << ", name="
          << reader.Get("user", "name", "UNKNOWN") << ", active="
          << reader.GetBoolean("user", "active", true) << "\n";

저자는 또한 여기 에 기존 라이브러리 목록이 있습니다 .


libconfig 를 사용해 보셨습니까 ? 매우 JSON과 유사한 구문입니다. XML 구성 파일보다 선호합니다.


플랫폼 이식성에 관심이있는 경우 Boost.PropertyTree를 사용해 볼 수도 있습니다. 속성 트리는 1 레벨 깊이이지만 ini를 지속성 형식으로 지원합니다.


앱을 크로스 플랫폼으로 만들 계획이 없다면 Windows API 호출을 사용하는 것이 가장 좋은 방법입니다. 16 비트 앱 호환성에 대해서만 제공된다는 API 문서의 참고 사항을 무시하십시오.


늦게 대답 할 수도 있지만 옵션을 알아볼 가치가 있습니다. 크로스 플랫폼 솔루션이 필요한 경우 GLIB를 사용해 볼 수 있습니다. 흥미로운 .. ( https://developer.gnome.org/glib/stable/glib- 키-값-파일 -parser.html )


나는이 질문이 매우 오래되었다는 것을 알고 있지만 Linux, win32에 대한 크로스 플랫폼이 필요했기 때문에 발생했습니다. 아래 함수를 작성했습니다. INI 파일을 구문 분석 할 수있는 단일 함수이므로 다른 사람들이 유용하다고 생각합니다.

규칙 및주의 사항 : 구문 분석 할 buf는 NULL로 끝나는 문자열이어야합니다. ini 파일을 char 배열 문자열로로드하고이 함수를 호출하여 구문 분석하십시오. 섹션 이름에는이 [MySection]과 같이 [] 대괄호가 있어야하며 값과 섹션은 선행 공백없이 행에서 시작해야합니다. Windows \ r \ n 또는 Linux \ n 줄 끝으로 파일을 구문 분석합니다. 주석은 # 또는 //를 사용하고 파일 맨 위에서 시작해야하며 주석은 INI 항목 데이터와 혼합되어서는 안됩니다. 따옴표와 눈금은 반환 문자열의 양쪽 끝에서 잘립니다. 공백은 따옴표 밖에있는 경우에만 잘립니다. 문자열에는 따옴표가 필요하지 않으며 따옴표가 없으면 공백이 잘립니다. 숫자 나 다른 데이터를 추출 할 수도 있습니다. 예를 들어 float가있는 경우 ret 버퍼에서 atof (ret)를 수행합니다.

//  -----note: no escape is nessesary for inner quotes or ticks-----
//  -----------------------------example----------------------------
//  [Entry2]
//  Alignment   = 1
//  LightLvl=128
//  Library     = 5555
//  StrValA =  Inner "quoted" or 'quoted' strings are ok to use
//  StrValB =  "This a "quoted" or 'quoted' String Value"
//  StrValC =  'This a "tick" or 'tick' String Value'
//  StrValD =  "Missing quote at end will still work
//  StrValE =  This is another "quote" example
//  StrValF =  "  Spaces inside the quote are preserved "
//  StrValG =  This works too and spaces are trimmed away
//  StrValH =
//  ----------------------------------------------------------------
//12oClocker super lean and mean INI file parser (with section support)
//set section to 0 to disable section support
//returns TRUE if we were able to extract a string into ret value
//NextSection is a char* pointer, will be set to zero if no next section is found
//will be set to pointer of next section if it was found.
//use it like this... char* NextSection = 0;  GrabIniValue(X,X,X,X,X,&NextSection);
//buf is data to parse, ret is the user supplied return buffer
BOOL GrabIniValue(char* buf, const char* section, const char* valname, char* ret, int retbuflen, char** NextSection)
{
    if(!buf){*ret=0; return FALSE;}

    char* s = buf; //search starts at "s" pointer
    char* e = 0;   //end of section pointer

    //find section
    if(section)
    {
        int L = strlen(section);
        SearchAgain1:
        s = strstr(s,section); if(!s){*ret=0; return FALSE;}    //find section
        if(s > buf && (*(s-1))!='\n'){s+=L; goto SearchAgain1;} //section must be at begining of a line!
        s+=L;                                                   //found section, skip past section name
        while(*s!='\n'){s++;} s++;                              //spin until next line, s is now begining of section data
        e = strstr(s,"\n[");                                    //find begining of next section or end of file
        if(e){*e=0;}                                            //if we found begining of next section, null the \n so we don't search past section
        if(NextSection)                                         //user passed in a NextSection pointer
        { if(e){*NextSection=(e+1);}else{*NextSection=0;} }     //set pointer to next section
    }

    //restore char at end of section, ret=empty_string, return FALSE
    #define RESTORE_E     if(e){*e='\n';}
    #define SAFE_RETURN   RESTORE_E;  (*ret)=0;  return FALSE

    //find valname
    int L = strlen(valname);
    SearchAgain2:
    s = strstr(s,valname); if(!s){SAFE_RETURN;}             //find valname
    if(s > buf && (*(s-1))!='\n'){s+=L; goto SearchAgain2;} //valname must be at begining of a line!
    s+=L;                                                   //found valname match, skip past it
    while(*s==' ' || *s == '\t'){s++;}                      //skip spaces and tabs
    if(!(*s)){SAFE_RETURN;}                                 //if NULL encounted do safe return
    if(*s != '='){goto SearchAgain2;}                       //no equal sign found after valname, search again
    s++;                                                    //skip past the equal sign
    while(*s==' '  || *s=='\t'){s++;}                       //skip spaces and tabs
    while(*s=='\"' || *s=='\''){s++;}                       //skip past quotes and ticks
    if(!(*s)){SAFE_RETURN;}                                 //if NULL encounted do safe return
    char* E = s;                                            //s is now the begining of the valname data
    while(*E!='\r' && *E!='\n' && *E!=0){E++;} E--;         //find end of line or end of string, then backup 1 char
    while(E > s && (*E==' ' || *E=='\t')){E--;}             //move backwards past spaces and tabs
    while(E > s && (*E=='\"' || *E=='\'')){E--;}            //move backwards past quotes and ticks
    L = E-s+1;                                              //length of string to extract NOT including NULL
    if(L<1 || L+1 > retbuflen){SAFE_RETURN;}                //empty string or buffer size too small
    strncpy(ret,s,L);                                       //copy the string
    ret[L]=0;                                               //null last char on return buffer
    RESTORE_E;
    return TRUE;

    #undef RESTORE_E
    #undef SAFE_RETURN
}

사용 방법 ... 예 ....

char sFileData[] = "[MySection]\r\n"
"MyValue1 = 123\r\n"
"MyValue2 = 456\r\n"
"MyValue3 = 789\r\n"
"\r\n"
"[MySection]\r\n"
"MyValue1 = Hello1\r\n"
"MyValue2 = Hello2\r\n"
"MyValue3 = Hello3\r\n"
"\r\n";
char str[256];
char* sSec = sFileData;
char secName[] = "[MySection]"; //we support sections with same name
while(sSec)//while we have a valid sNextSec
{
    //print values of the sections
    char* next=0;//in case we dont have any sucessful grabs
    if(GrabIniValue(sSec,secName,"MyValue1",str,sizeof(str),&next)) { printf("MyValue1 = [%s]\n",str); }
    if(GrabIniValue(sSec,secName,"MyValue2",str,sizeof(str),0))     { printf("MyValue2 = [%s]\n",str); }
    if(GrabIniValue(sSec,secName,"MyValue3",str,sizeof(str),0))     { printf("MyValue3 = [%s]\n",str); }
    printf("\n");
    sSec = next; //parse next section, next will be null if no more sections to parse
}

I ended up using inipp which is not mentioned in this thread.

https://github.com/mcmtroffaes/inipp

Was a MIT licensed header only implementation which was simple enough to add to a project and 4 lines to use.

참고URL : https://stackoverflow.com/questions/12633/what-is-the-easiest-way-to-parse-an-ini-file-in-c

반응형