Saya mencoba mengurai file INI menggunakan C ++. Adakah tip tentang cara terbaik untuk mencapai ini? Haruskah saya menggunakan alat Windows API untuk pemrosesan file INI (yang sama sekali tidak saya kenal), solusi open-source atau mencoba menguraikannya secara manual?
89
Jika Anda memerlukan solusi lintas platform, coba pustaka Opsi Program Boost .
sumber
Saya tidak pernah mengurai file ini, jadi saya tidak bisa terlalu spesifik tentang masalah ini.
Tetapi saya punya satu saran:
Jangan menemukan kembali roda selama yang sudah ada memenuhi kebutuhan Anda
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
Semoga berhasil :)
sumber
Jika Anda sudah menggunakan Qt
QSettings my_settings("filename.ini", QSettings::IniFormat);
Kemudian bacalah nilainya
my_settings.value("GroupName/ValueName", <<DEFAULT_VAL>>).toInt()
Ada banyak konverter lain yang mengubah nilai INI Anda menjadi tipe standar dan tipe Qt. Lihat dokumentasi Qt pada QSettings untuk informasi lebih lanjut.
sumber
sync()
, yang bisa menjadi kejutan) dan itu menghancurkan komentar dan urutan variabel yang didefinisikan sebelumnya ...Saya menggunakan SimpleIni . Ini lintas platform.
sumber
pertanyaan ini agak tua, tapi saya akan memposting jawaban saya. Saya telah menguji berbagai kelas INI (Anda dapat melihatnya di situs web saya ) dan saya juga menggunakan simpleIni karena saya ingin bekerja dengan file INI di windows dan winCE. GetPrivateProfileString () Window hanya berfungsi dengan registri di winCE.
Sangat mudah dibaca dengan simpleIni. Berikut ini contohnya:
#include "SimpleIni\SimpleIni.h" CSimpleIniA ini; ini.SetUnicode(); ini.LoadFile(FileName); const char * pVal = ini.GetValue(section, entry, DefaultStr);
sumber
inih adalah parser ini sederhana yang ditulis dalam C, dilengkapi dengan pembungkus C ++ juga. Contoh penggunaan:
#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";
Penulis juga memiliki daftar pustaka yang ada di sini .
sumber
Sudahkah Anda mencoba libconfig ; sangat mirip dengan sintaks JSON. Saya lebih suka daripada file konfigurasi XML.
sumber
Jika Anda tertarik dengan portabilitas platform, Anda juga dapat mencoba Boost.PropertyTree. Ini mendukung ini sebagai format persistensi, meskipun pohon properti saya hanya sedalam 1 tingkat.
sumber
Kecuali Anda berencana membuat aplikasi lintas platform, menggunakan panggilan Windows API akan menjadi cara terbaik untuk melakukannya. Abaikan saja catatan dalam dokumentasi API tentang hanya disediakan untuk kompatibilitas aplikasi 16-bit.
sumber
Mungkin jawaban yang terlambat..Tapi, pilihan yang perlu diketahui..Jika Anda membutuhkan solusi lintas platform, pasti Anda dapat mencoba GLIB ,, menarik .. ( https://developer.gnome.org/glib/stable/glib- File-nilai-kunci-parser.html )
sumber
Saya tahu pertanyaan ini sangat tua, tetapi saya mendapatkannya karena saya membutuhkan sesuatu lintas platform untuk linux, win32 ... Saya menulis fungsi di bawah ini, ini adalah fungsi tunggal yang dapat mengurai file INI, semoga orang lain akan menganggapnya berguna.
rules & caveats: buf to parse harus berupa string yang diakhiri NULL. Muat file ini Anda ke dalam string array karakter dan panggil fungsi ini untuk menguraikannya. nama bagian harus memiliki tanda kurung [] di sekelilingnya, seperti [MySection] ini, juga nilai dan bagian harus dimulai pada baris tanpa spasi. Ini akan mengurai file dengan Windows \ r \ n atau dengan Linux \ n akhiran baris. Komentar harus menggunakan # atau // dan dimulai dari bagian atas file, tidak ada komentar yang dicampur dengan data entri INI. Kutipan dan centang dipangkas dari kedua ujung string kembali. Spasi hanya dipangkas jika berada di luar kutipan. String tidak harus memiliki tanda kutip, dan spasi kosong dipangkas jika tanda kutip tidak ada. Anda juga dapat mengekstrak angka atau data lain, misalnya jika Anda memiliki float, lakukan saja atof (ret) pada buffer 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 }
Cara menggunakan ... contoh ....
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 }
sumber
Saya akhirnya menggunakan inipp yang tidak disebutkan di utas ini.
https://github.com/mcmtroffaes/inipp
Apakah hanya implementasi header berlisensi MIT yang cukup sederhana untuk ditambahkan ke proyek dan 4 baris untuk digunakan.
sumber