我试图解析使用C ++ INI文件。 什么任何提示是实现这一目标的最佳途径? 我应该使用INI文件处理的Windows API工具(与我完全不熟悉),一个开放源代码解决方案或尝试手动分析它?
Answer 1:
您可以使用Windows API函数,比如GetPrivateProfileString()和GetPrivateProfileInt() 。
Answer 2:
如果你需要一个跨平台的解决方案,尝试Boost的程序选项库。
Answer 3:
我从来没有解析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
祝好运 :)
Answer 4:
我用SimpleIni 。 它是跨平台的。
Answer 5:
如果您已经使用Qt
QSettings my_settings("filename.ini", QSettings::IniFormat);
然后读取值
my_settings.value("GroupName/ValueName", <<DEFAULT_VAL>>).toInt()
有迹象表明,将您的INI值到这两种标准类型和Qt其他类型转换器的一群。 查看QSettings Qt文档以获取更多信息。
Answer 6:
这个问题是有点老了,但我会后我的答案。 我已经尝试了各种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);
Answer 7:
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";
笔者也有现有的库列表在这里 。
Answer 8:
你试过libconfig ; 很JSON的语法。 我喜欢它在XML配置文件。
Answer 9:
如果你有兴趣在平台的可移植性,你也可以尝试Boost.PropertyTree。 它支持INI为persistancy格式,虽然属性树我是1级深而已。
Answer 10:
除非你打算使应用程序跨平台,使用Windows API调用将是最好的一段路要走。 不理会有关只为16位应用程序的兼容性而提供的API文档中的注意事项。
Answer 11:
也许一晚answer..But,值得了解options..If你需要一个跨平台的解决方案,绝对可以尝试GLIB ,,其有趣..( https://developer.gnome.org/glib/stable/glib-键值文件parser.html )
Answer 12:
我知道这个问题是很老了,但是我来到它,因为我需要的东西跨平台的Linux,win32的......我写了下面的功能,它是一个可以解析INI文件的单一功能,希望别人会发现它很有用。
规则及注意事项:BUF解析必须是一个NULL结尾的字符串。 载入你的ini文件到一个字符数组字符串和调用这个函数来分析它。 节名称必须有[]他们周围的括号,比如这个[MySection],也价值观和部分必须在一行开始没有前导空格。 它将分析文件与Windows \ r \ n或使用Linux \ 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
}
如何使用...例如....
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
}
Answer 13:
我结束了使用未在此线程提到inipp。
https://github.com/mcmtroffaes/inipp
当时这是很简单的添加到项目和4线使用MIT许可的头只执行。