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
'IT story' 카테고리의 다른 글
iOS7에서 동적 텍스트 크기로 사용자 정의 글꼴을 사용하는 방법 (0) | 2020.09.13 |
---|---|
Android Studio : Gradle을 사용하여 서명 된 APK를 생성하는 방법은 무엇입니까? (0) | 2020.09.13 |
Android에서 이미지를 다운로드하고 저장하는 방법 (0) | 2020.09.12 |
iOS7에서 투명한 UIToolbar 또는 UINavigationBar를 그리는 방법 (0) | 2020.09.12 |
ngStyle (angular2)을 사용하여 배경 이미지를 추가하는 방법은 무엇입니까? (0) | 2020.09.12 |