Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C+;中解析INI文件的最简单方法是什么+;? 我试图用C++解析ini文件。关于实现这一目标的最佳方法有什么建议吗?我应该使用Windows API工具来处理INI文件(我对此完全不熟悉)、开源解决方案还是尝试手动解析它?_C++_Winapi_Ini_Fileparse - Fatal编程技术网

在C+;中解析INI文件的最简单方法是什么+;? 我试图用C++解析ini文件。关于实现这一目标的最佳方法有什么建议吗?我应该使用Windows API工具来处理INI文件(我对此完全不熟悉)、开源解决方案还是尝试手动解析它?

在C+;中解析INI文件的最简单方法是什么+;? 我试图用C++解析ini文件。关于实现这一目标的最佳方法有什么建议吗?我应该使用Windows API工具来处理INI文件(我对此完全不熟悉)、开源解决方案还是尝试手动解析它?,c++,winapi,ini,fileparse,C++,Winapi,Ini,Fileparse,我从来没有解析过INI文件,所以我不能对这个问题说得太具体。 但我有一个建议: 只要现有车轮满足您的要求,就不要重新发明车轮 祝您好运:)您可以使用Windows API函数,如和。除非您计划使应用程序跨平台,否则使用Windows API调用将是最好的方法。只需忽略API文档中关于仅为16位应用程序兼容性而提供的注释。如果需要跨平台解决方案,请尝试Boost的库。我使用它。它是跨平台的。你试过了吗;非常类似JSON的语法。与XML配置文件相比,我更喜欢它。这个问题有点老了,但我会发布我

我从来没有解析过INI文件,所以我不能对这个问题说得太具体。
但我有一个建议:
只要现有车轮满足您的要求,就不要重新发明车轮





祝您好运:)

您可以使用Windows API函数,如和。

除非您计划使应用程序跨平台,否则使用Windows API调用将是最好的方法。只需忽略API文档中关于仅为16位应用程序兼容性而提供的注释。

如果需要跨平台解决方案,请尝试Boost的库。

我使用它。它是跨平台的。

你试过了吗;非常类似JSON的语法。与XML配置文件相比,我更喜欢它。

这个问题有点老了,但我会发布我的答案。我已经测试了各种INI类(你可以在我的上看到它们),我也使用simpleIni,因为我想在windows和winCE上使用INI文件。 窗口的GetPrivateProfileString()仅适用于winCE上的注册表

使用simpleIni很容易阅读。以下是一个例子:

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

如果您已经在使用Qt

QSettings my_settings("filename.ini", QSettings::IniFormat);
然后读取一个值

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

还有一些其他转换器可以将INI值转换为标准类型和Qt类型。有关更多信息,请参阅QSettings上的Qt文档。

如果您对平台可移植性感兴趣,也可以尝试Boost.PropertyTree。它支持INI作为持久性格式,虽然属性树只有1级深度。

是一个简单的INI解析器,用C编写,它也带有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";
#包括“INIReader.h”
InReader阅读器(“test.ini”);

std::cout可能是一个迟来的答案..但是,值得了解的选项..如果您需要跨平台解决方案,您肯定可以尝试GLIB,,这很有趣。。()

我知道这个问题已经很老了,但我遇到这个问题是因为我需要一些跨平台的linux、win32。。。我写了下面的函数,它是一个可以解析INI文件的函数,希望其他人会发现它很有用

规则和注意事项: 要分析的buf必须是以NULL结尾的字符串。将ini文件加载到字符数组字符串中,并调用此函数对其进行解析。 节名周围必须有[]方括号,例如[MySection],并且值和节必须以不带前导空格的行开头。它将用Windows或Linux行结尾\r\n解析文件。注释应使用#或//并从文件顶部开始,任何注释都不应与INI条目数据混合。引号和记号从返回字符串的两端修剪。仅当空格在报价之外时,才会修剪空格。字符串不需要加引号,如果缺少引号,则会修剪空白。您还可以提取数字或其他数据,例如,如果您有一个浮点,只需在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
}

我最终使用了本帖中未提及的InApp


这是一个MIT授权的只包含标题的实现,非常简单,可以添加到一个项目中并使用4行。

这是一个方法,我不明白为什么人们投票不这么笼统。@Gollum,听起来Windows是一个给定的依赖项。使用程序选项库意味着接受另一个依赖项。有时这没什么大不了的,有时的确如此。Boost的程序选项似乎使用它自己的配置格式,哈希符号(#)用于注释(而不是分号)@malat我很困惑,我没有提到向下投票?他正在尝试读取现有的INI文件,使用boost不是答案,因为它使用的是类似INI的格式。SimpleIni现在托管在Github中。它似乎支持Visual Studio和GCC、MIT许可证。截至撰写本文时,它的自动构建正在失败,最后一次发布是在2013年9月,最后一次提交:2020年6月,还不错,不过如果您进行更改,它们会在没有真正告诉您的情况下将更改保存回.ini文件(即析构函数调用
sync()
,这可能会让人吃惊)这破坏了之前定义变量的注释和顺序……MSDN不推荐使用GetPrivateProfileInt()和其他函数,因为它们已经过时,并且仍然仅为与旧的16位系统兼容而提供。而不是使用其他方法。它们已经过时了,因为MS不想让您再使用ini文件,如果您真的想读或写这样的文件,它们仍然是理想的。
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
}