Tôi biết câu hỏi này rất cũ, nhưng tôi nghĩ đến nó vì tôi cần một cái gì đó đa nền tảng cho linux, win32 ... Tôi đã viết hàm dưới đây, nó là một hàm duy nhất có thể phân tích cú pháp tệp INI, hy vọng những người khác sẽ thấy nó hữu ích.
quy tắc & lưu ý: buf để phân tích cú pháp phải là một chuỗi kết thúc NULL. Tải tệp ini của bạn vào một chuỗi mảng char và gọi hàm này để phân tích cú pháp. tên phần phải có dấu ngoặc [] xung quanh chúng, chẳng hạn như [MySection] này, các giá trị và phần phải bắt đầu trên một dòng không có dấu cách ở đầu. Nó sẽ phân tích cú pháp tệp với Windows \ r \ n hoặc với phần cuối dòng Linux \ n. Nhận xét nên sử dụng # hoặc // và bắt đầu ở đầu tệp, không nhận xét nào được trộn lẫn với dữ liệu nhập INI. Dấu ngoặc kép và dấu tích được cắt từ cả hai đầu của chuỗi trả về. Khoảng trắng chỉ được cắt bớt nếu chúng nằm ngoài phần trích dẫn. Các chuỗi không bắt buộc phải có dấu ngoặc kép và khoảng trắng được cắt bớt nếu thiếu dấu ngoặc kép. Bạn cũng có thể trích xuất các số hoặc dữ liệu khác, chẳng hạn như nếu bạn có một float, chỉ cần thực hiện một atof (ret) trên bộ đệm ret.
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;
char* e = 0;
if(section)
{
int L = strlen(section);
SearchAgain1:
s = strstr(s,section); if(!s){*ret=0; return FALSE;}
if(s > buf && (*(s-1))!='\n'){s+=L; goto SearchAgain1;}
s+=L;
while(*s!='\n'){s++;} s++;
e = strstr(s,"\n[");
if(e){*e=0;}
if(NextSection)
{ if(e){*NextSection=(e+1);}else{*NextSection=0;} }
}
#define RESTORE_E if(e){*e='\n';}
#define SAFE_RETURN RESTORE_E; (*ret)=0; return FALSE
int L = strlen(valname);
SearchAgain2:
s = strstr(s,valname); if(!s){SAFE_RETURN;}
if(s > buf && (*(s-1))!='\n'){s+=L; goto SearchAgain2;}
s+=L;
while(*s==' ' || *s == '\t'){s++;}
if(!(*s)){SAFE_RETURN;}
if(*s != '='){goto SearchAgain2;}
s++;
while(*s==' ' || *s=='\t'){s++;}
while(*s=='\"' || *s=='\''){s++;}
if(!(*s)){SAFE_RETURN;}
char* E = s;
while(*E!='\r' && *E!='\n' && *E!=0){E++;} E--;
while(E > s && (*E==' ' || *E=='\t')){E--;}
while(E > s && (*E=='\"' || *E=='\'')){E--;}
L = E-s+1;
if(L<1 || L+1 > retbuflen){SAFE_RETURN;}
strncpy(ret,s,L);
ret[L]=0;
RESTORE_E;
return TRUE;
#undef RESTORE_E
#undef SAFE_RETURN
}
Cách sử dụng… ví dụ….
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]";
while(sSec)
{
char* next=0;
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;
}