2008-08-15 8 views
80

मैं सी ++ का उपयोग कर आईएनआई फ़ाइल को पार्स करने की कोशिश कर रहा हूं। इस पर कोई सुझाव नहीं है कि इसे हासिल करने का सबसे अच्छा तरीका क्या है? क्या मुझे आईएनआई फाइल प्रोसेसिंग के लिए विंडोज एपीआई टूल्स का उपयोग करना चाहिए (जिसके साथ मैं पूरी तरह से अपरिचित हूं), ओपन-सोर्स सॉल्यूशन या इसे मैन्युअल रूप से पार्स करने का प्रयास?सी ++ में आईएनआई फ़ाइल को पार्स करने का सबसे आसान तरीका क्या है?

उत्तर

106

आप विंडोज एपीआई फ़ंक्शंस का उपयोग कर सकते हैं, सफल एच GetPrivateProfileString() और GetPrivateProfileInt() के रूप में।

+0

GetPrivateProfileInt() और अन्य कार्यों MSDN द्वारा अनुशंसित नहीं हैं, क्योंकि वे पुराने पड़ चुके हैं और अभी भी पुराने के साथ ही baskward संगतता के लिए प्रदान की जाती हैं, 16-बिट सिस्टम। इसके बजाय अन्य दृष्टिकोण का उपयोग करें। https://msdn.microsoft.com/en-us/library/windows/desktop/ms724345(v=vs.85).aspx –

23

मैं 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

गुड लक :)

का पालन करता हैं:
लेकिन मैं एक सलाह है
2

जब तक आप एप्लिकेशन पार मंच बनाने, विंडोज API कॉल का उपयोग कर जाने के लिए सबसे अच्छा तरीका है पर योजना। केवल 16-बिट ऐप संगतता के लिए प्रदान किए जाने के बारे में API दस्तावेज़ में नोट को अनदेखा करें।

109

आप एक पार मंच समाधान की जरूरत है, बूस्ट के Program Options पुस्तकालय का प्रयास करें।

+0

मैं इस लाइब्रेरी को भी सुझाव दूंगा – varnie

+18

यह जाने का तरीका है, मैं नहीं करता हूं ' टी समझ में नहीं आता क्यों लोग सिर्फ सामान्य जवाब नहीं देते हैं। –

+15

@ गॉलम, ऐसा लगता है जैसे विंडोज एक निर्भरता है। प्रोग्राम विकल्प लाइब्रेरी का उपयोग करना एक और निर्भरता लेना है। कभी-कभी यह एक बड़ा सौदा नहीं है, कभी-कभी यह होता है। –

16

मैं SimpleIni का उपयोग करता हूं। यह क्रॉस-प्लेटफार्म है।

+1

utf-16 का समर्थन नहीं करता है :(क्यों ??? – DiGMi

+0

सरलइनी अब गिथब में होस्ट किया गया है। –

+1

https://github.com/brofield/simpleini – Katu

4

आप libconfig की कोशिश की है; बहुत JSON- जैसे वाक्यविन्यास। मैं इसे एक्सएमएल विन्यास फाइलों पर पसंद करता हूं।

8

यह प्रश्न थोड़ा पुराना है, लेकिन मैं अपना जवाब पोस्ट करूंगा। मैंने विभिन्न आईएनआई कक्षाओं का परीक्षण किया है (आप उन्हें अपने website पर देख सकते हैं) और मैं सरलइनी का भी उपयोग करता हूं क्योंकि मैं विंडोज़ और विनसी दोनों पर आईएनआई फाइलों के साथ काम करना चाहता हूं। विंडो का GetPrivateProfileString() केवल WinCE पर रजिस्ट्री के साथ काम करता है।

सरलइनी के साथ पढ़ना बहुत आसान है। यहाँ एक उदाहरण है:

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

आप पहले से ही क्यूटी

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

उपयोग कर रहे हैं तो एक मूल्य पढ़

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

अन्य कनवर्टर का एक समूह है कि दोनों में अपने INI मान परिवर्तित कर रहे हैं मानक प्रकार और क्यूटी प्रकार। अधिक जानकारी के लिए QSettings पर क्यूटी दस्तावेज देखें।

+0

बुरा नहीं है, हालांकि यदि आप परिवर्तन करते हैं तो वे उन्हें वापस सहेजते हैं। वास्तव में आपको बताए बिना आईएनआई फ़ाइल (यानी विनाशक 'सिंक()' कहता है, जो आश्चर्यचकित हो सकता है) और जो टिप्पणियों और क्रम को नष्ट कर देता है जिसमें चर को पहले परिभाषित किया गया था ... –

3

आप मंच पोर्टेबिलिटी में रुचि रखते हैं, तो आप भी Boost.PropertyTree कोशिश कर सकते हैं। यह ini को दृढ़ता प्रारूप के रूप में समर्थन करता है, हालांकि संपत्ति का पेड़ केवल 1 स्तर गहरा होना चाहिए।

5

inih एक सरल आरं सी में लिखे पार्सर है, यह एक सी ++ आवरण भी साथ आता है। उदाहरण उपयोग:

#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"; 

लेखक भी मौजूदा पुस्तकालयों here की एक सूची है।

1

हो सकता है कि एक देर answer..But, जानते हुए भी options..If आप एक पार मंच समाधान की जरूरत के लायक, निश्चित रूप से आप GLib कोशिश कर सकते हैं ,, अपनी दिलचस्प .. (https://developer.gnome.org/glib/stable/glib-Key-value-file-parser.html)

0

मैं जानता हूँ कि इस सवाल का बहुत है पुराना, लेकिन मैं इस पर आया क्योंकि मुझे लिनक्स, win32 के लिए कुछ क्रॉस प्लेटफ़ॉर्म चाहिए ... मैंने नीचे दिया गया फ़ंक्शन लिखा है, यह एक ऐसा फ़ंक्शन है जो आईएनआई फाइलों को पार्स कर सकता है, उम्मीद है कि दूसरों को यह उपयोगी लगेगा।

नियम & चेतावनी: पार्स को पार्स एक पूर्ण समाप्त स्ट्रिंग होना चाहिए। अपनी आईएनआई फ़ाइल को चार सरणी स्ट्रिंग में लोड करें और इस फ़ंक्शन को पार्स करने के लिए कॉल करें। अनुभाग नामों में उनके चारों ओर ब्रैकेट होना चाहिए, जैसे कि [MySection], मूल्य भी और बिना किसी रिक्त स्थान के अनुभागों को लाइन पर शुरू होना चाहिए। यह Windows \ r \ n या Linux \ n लाइन समाप्ति के साथ फ़ाइलों को पार्स करेगा। टिप्पणियों को # या // का उपयोग करना चाहिए और फ़ाइल के शीर्ष पर शुरू होना चाहिए, आईएनआई प्रविष्टि डेटा के साथ कोई टिप्पणी मिश्रित नहीं की जानी चाहिए। उद्धरण और टिक वापसी रिटर्न के दोनों सिरों से छंटनी की जाती हैं। रिक्त स्थान केवल तभी छिड़के जाते हैं जब वे उद्धरण के बाहर हों। स्ट्रिंग्स को कोट्स रखने की आवश्यकता नहीं है, और उद्धरण गुम होने पर सफेद जगहों को छंटनी की जाती है। आप संख्याओं या अन्य डेटा को भी निकाल सकते हैं, उदाहरण के लिए यदि आपके पास फ्लोट है तो बस बफर पर एटॉफ (रेट) करें।

// -----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 
} 
संबंधित मुद्दे