相信很多朋友在编写自己的程序中,都需要把一些数据先期导入到程序中进行初始化。那么这个时候,比较好的做法就是把你所有的数据写入一个ini文件,然后在程序去读ini文件中的数据对行初始化。
一.INI简介
那么什么是ini文件呢?ini文件是Initialization file的缩写,意即初始化文件。(从名字就可以看出它的功能了吧)。不仅你自己的程序可以使用ini文件,其实windows操作系统也有自己的ini文件---win.ini,保存在%WinDir%\system32目录下。Windows通过该文件对当前操作系统进行配置。
ini文件里的数据的存取是采取的是预先约定好的 “项-值”存储结构,各种数据被分门别类的存储。以下是win.ini 文件的部分内容。
[Mail]
MAPI=1
CMC=1
CMCDLLNAME=mapi.dll
CMCDLLNAME32=mapi32.dll
MAPIX=1
MAPIXVER=1.0.0.1
OLEMessaging=1
表1
通过以上内容,我们可以看到,ini文件将各种数据分成很多以“[ ]”组成的节,而在每一个“节”中又包含了很多“项”,“项”后面紧跟着一个等号,等号后面则是该项的值。在该例中[Mail]就是一个“节”,MAPI是一个项,1则是MAPI的值。
所以,它的通用形式我们可以总结成:
[Section]
Key=KeyValue
二.操作ini文件的API
windows SDK提供有两组API对ini文件进行读写。
读
写
GetPrivateProfileString
GetPrivateProfileInt
WritePrivateProfileString
GetPrivateProfileSection
WritePrivateProfileSection
GetPrivateProfileSectionNames
GetPrivateProfileStruct
WritePrivateProfileStruct
表2
读
写
GetProfileString
GetProfileInt
WriteProfileString
GetProfileSection
WritePrivateProfileSection
表3
对用户的配置文件来说,一般我们使用的是表2中的函数,这一点从函数中的“private”就可以看出它是针对私有的配置文件的函数(又是废话!)。而表3中的函数则是提供给针对系统配置文件,即win.ini进行操作的函数。现只准备介绍表2中的函数,这也是使用率最高的,表3中的函数操作和表2中的函数操作类同,故略。
现在我们来看看这几个函数的功能:
DWORD GetPrivateProfileString(
LPCTSTR lpAppName, //节名,即Section
LPCTSTR lpKeyName, //项名,即Key
LPCTSTR lpDefault, //缺省返回字符串。如lpKeyName未找到,拷贝lpDefault到lpReturnedString
LPTSTR lpReturnedString, //返回字符串的缓冲地址
DWORD nSize, //缓冲大小
LPCTSTR lpFileName //ini文件路径
);
功能:根据指定的Section和 Key得到KeyValue,存放在lpReturnedString中
返回:返回拷贝到缓冲中的字符个数。不包括结束符
UINT GetPrivateProfileInt(
LPCTSTR lpAppName, //节名,即Section
LPCTSTR lpKeyName, //项名,即Key
INT nDefault, //缺省返回整型值。如lpKeyName未找到,函数返回nDefault的值
LPCTSTR lpFileName //ini文件路径
);
功能:根据指定的Section和 Key得到整型KeyValue
返回:返回得到的整型KeyValue
BOOL WritePrivateProfileString(
LPCTSTR lpAppName, //节名,即Section
LPCTSTR lpKeyName, //项名,即Key
LPCTSTR lpString, //要写入的字符串
LPCTSTR lpFileName //ini文件路径
);
功能:向指定的Section和 Key写入KeyValue。
如果lpString为NULL,则删除当前lpKeyName
如果lpKeyName=lpString=NULL,则删除当前Section以及其下的所有Key
如果Section或者Key不存在,则创建;存在则覆盖
返回:写入成功。
DWORD GetPrivateProfileSectionNames(
LPTSTR lpszReturnBuffer, //存放所有Section的缓冲地址
DWORD nSize, //缓冲大小
LPCTSTR lpFileName //ini文件路径
);
功能:得到ini文件中所有Section名。
返回:返回拷贝到缓冲中的字符个数。不包括结束符。
注意:返回的所有Section在缓冲中的存放格式为“Section1”,0,“Section2”,0。。。。
若需要得到具体的每个Section,则需要进行字符串解析。在后面的IniFile类中的GetAllKeysAndValues函数中会看到解
析步骤。
DWORD GetPrivateProfileSection(
LPCTSTR lpAppName, //节名,即Section
LPTSTR lpReturnedString, //存放指定Section下所有的Key和KeyValue的缓冲地址
DWORD nSize, //缓冲大小
LPCTSTR lpFileName //ini文件路径
);
功能:得到指定Section下所有的Key和KeyValue。
返回:返回拷贝到缓冲中的字符个数。不包括结束符。
注意:返回的“项-值对”在缓冲中的存放格式为“Key1=KeyValue1”,0,“Key2=KeyValue2”,0 。。。。
若需要得到具体的Key和KeyValue,则需要进行字符串解析。在后面的IniFile类中的GetAllKeysAndValues函数中会看到解析步骤。
GetPrivateProfileStruct和WritePrivateProfileStruct用的较少,本文也未介绍,感兴趣的朋友可以自己看看MSDN,里面也有详细介绍。
int cini::getsections(cstringarray& arrsection)
{
/*
本函数基础:
getprivateprofilesectionnames - 从 ini 文件中获得 section 的名称
如果 ini 中有两个 section: [sec1] 和 [sec2],则返回的是 sec1,0,sec2,0,0 ,当你不知道
ini 中有哪些 section 的时候可以用这个 api 来获取名称
*/
int i;
int ipos=0;
int imaxcount;
tchar chsectionnames[max_allsections]={0}; //总的提出来的字符串
tchar chsection[max_section]={0}; //存放一个段名。
getprivateprofilesectionnames(chsectionnames,max_allsections,m_strfilename);
//以下循环,截断到两个连续的0
for(i=0;i<max_allsections;i++)
{
if (chsectionnames[i]==0)
if (chsectionnames[i]==chsectionnames[i+1])
break;
}
imaxcount=i+1; //要多一个0号元素。即找出全部字符串的结束部分。
//arrsection.removeall();//清空原数组
for(i=0;i<imaxcount;i++)
{
chsection[ipos++]=chsectionnames[i];
if(chsectionnames[i]==0)
{
arrsection.add(chsection);
memset(chsection,0,i);
ipos=0;
}
}
return (int)arrsection.getsize();
}
//保存到配置文件中(.ini)
char exeFullPath[MAX_PATH];
GetModuleFileName(NULL,exeFullPath,MAX_PATH);//获得该程序的路径
CString temp = exeFullPath;
temp = temp.Left(temp.ReverseFind('\\'));
temp = temp+FILE_PARAMETER;
CString S,L,U,R,B,T;
GetDlgItemText(IDC_STATIC_SET_WORK_PULSE_S,S);
GetDlgItemText(IDC_STATIC_SET_WORK_PULSE_L,L);
GetDlgItemText(IDC_STATIC_SET_WORK_PULSE_U,U);
GetDlgItemText(IDC_STATIC_SET_WORK_PULSE_R,R);
GetDlgItemText(IDC_STATIC_SET_WORK_PULSE_B,B);
GetDlgItemText(IDC_STATIC_SET_WORK_PULSE_T,T);
WritePrivateProfileString("HomePosition","SAxisPulse",S,temp); //把数据保存在相应节名下的 项名中
WritePrivateProfileString("HomePosition","LAxisPulse",L,temp);
WritePrivateProfileString("HomePosition","UAxisPulse",U,temp);
WritePrivateProfileString("HomePosition","RAxisPulse",R,temp);
WritePrivateProfileString("HomePosition","BAxisPulse",B,temp);
WritePrivateProfileString("HomePosition","TAxisPulse",T,temp);
char exeFullPath[MAX_PATH];
GetModuleFileName(NULL,exeFullPath,MAX_PATH);//获得该程序的路径
CString temp = exeFullPath;
temp = temp.Left(temp.ReverseFind('\\'));
temp = temp+FILE_PARAMETER;
CString S,L,U,R,B,T;
GetDlgItemText(IDC_STATIC_SET_WORK_PULSE_S,S);
GetDlgItemText(IDC_STATIC_SET_WORK_PULSE_L,L);
GetDlgItemText(IDC_STATIC_SET_WORK_PULSE_U,U);
GetDlgItemText(IDC_STATIC_SET_WORK_PULSE_R,R);
GetDlgItemText(IDC_STATIC_SET_WORK_PULSE_B,B);
GetDlgItemText(IDC_STATIC_SET_WORK_PULSE_T,T);
WritePrivateProfileString("HomePosition","SAxisPulse",S,temp); //把数据保存在相应节名下的 项名中
WritePrivateProfileString("HomePosition","LAxisPulse",L,temp);
WritePrivateProfileString("HomePosition","UAxisPulse",U,temp);
WritePrivateProfileString("HomePosition","RAxisPulse",R,temp);
WritePrivateProfileString("HomePosition","BAxisPulse",B,temp);
WritePrivateProfileString("HomePosition","TAxisPulse",T,temp);
///从配置文件读取较准原点坐标数据
char exeFullPath[MAX_PATH];
GetModuleFileName(NULL,exeFullPath,MAX_PATH);
CString str=exeFullPath;
CString temp=str.Left(str.ReverseFind('\\'));
char AllSections[100];
GetPrivateProfileSectionNames(AllSections,100,temp); //得到所有节名
int imaxcount=0;
for(i=0;i<100;i++)
{
if(AllSections[i]==0 && AllSections[i]==AllSections[i+1]) //节名最后是2个0 ,依此判断有效节名的数
break;
}
imaxcount=i+1; //
int pos=0;int NumSections=0;
char section[100]={0};
CString SectionName[20];
for(i=0;i<imaxcount;i++)
{
section[pos++]=AllSections[i];
if(AllSections[i]==0)
{
SectionName[NumSections++]=section; //把所有的节名分别保存在SectionName中
pos=0;
memset(section,0,sizeof(section));
}
}
bool BhasHome=false,BhasLimitPosition=false;
for(i=0;i<NumSections;i++)
{
if(SectionName[i]=="HomePosition") //判断有没有"HomePosition"节名
BhasHome=true;
else if(SectionName[i]="LimitPosition") //判断有没有"LimitPosition"节名
BhasLimitPosition=true;
}
if(!BhasHome)
{
AfxMessageBox("没有设定原点,请设定原点!");
return;
}
if(BhasLimitPosition)
{
AfxMessageBox("没有设定软限位,请设定软限位!");
return;
}
char SPulse[20],LPulse[20],UPulse[20],RPulse[20],BPulse[20],TPulse[20]; //获取相应节名下,相应项名数据
GetPrivateProfileString("HomePosition","SAxisPulse",0,SPulse,20,temp);
GetPrivateProfileString("HomePosition","LAxisPulse",0,LPulse,20,temp);
GetPrivateProfileString("HomePosition","UAxisPulse",0,UPulse,20,temp);
GetPrivateProfileString("HomePosition","RAxisPulse",0,RPulse,20,temp);
GetPrivateProfileString("HomePosition","BAxisPulse",0,BPulse,20,temp);
GetPrivateProfileString("HomePosition","TAxisPulse",0,TPulse,20,temp);
absPulse[0]=atol(SPulse);
absPulse[1]=atol(LPulse);
absPulse[2]=atol(UPulse);
absPulse[3]=atol(RPulse);
absPulse[4]=atol(BPulse);
absPulse[5]=atol(TPulse);
//以下是软限位设置
char SoftLimitPS[20],SoftLimitNS[20],SoftLimitPL[20],SoftLimitNL[20],SoftLimitPU[20],SoftLimitNU[20];
char SoftLimitPR[20],SoftLimitNR[20],SoftLimitPB[20],SoftLimitNB[20],SoftLimitPT[20],SoftLimitNT[20];
GetPrivateProfileString("LimitPosition","S+",0,SoftLimitPS,20,temp);
GetPrivateProfileString("LimitPosition","S-",0,SoftLimitNS,20,temp);
GetPrivateProfileString("LimitPosition","L+",0,SoftLimitPL,20,temp);
GetPrivateProfileString("LimitPosition","L-",0,SoftLimitNL,20,temp);
GetPrivateProfileString("LimitPosition","U+",0,SoftLimitPU,20,temp);
GetPrivateProfileString("LimitPosition","U-",0,SoftLimitNU,20,temp);
GetPrivateProfileString("LimitPosition","R+",0,SoftLimitPR,20,temp);
GetPrivateProfileString("LimitPosition","R-",0,SoftLimitNR,20,temp);
GetPrivateProfileString("LimitPosition","B+",0,SoftLimitPB,20,temp);
GetPrivateProfileString("LimitPosition","B-",0,SoftLimitNB,20,temp);
GetPrivateProfileString("LimitPosition","T+",0,SoftLimitPT,20,temp);
GetPrivateProfileString("LimitPosition","T-",0,SoftLimitNT,20,temp);
long SoftLimit[12];
SoftLimit[0]=atol(SoftLimitNS);
SoftLimit[1]=atol(SoftLimitPS);
SoftLimit[2]=atol(SoftLimitNL);
SoftLimit[3]=atol(SoftLimitPL);
SoftLimit[4]=atol(SoftLimitNU);
SoftLimit[5]=atol(SoftLimitPU);
SoftLimit[6]=atol(SoftLimitNR);
SoftLimit[7]=atol(SoftLimitPR);
SoftLimit[8]=atol(SoftLimitNB);
SoftLimit[9]=atol(SoftLimitPB);
SoftLimit[10]=atol(SoftLimitNT);
SoftLimit[11]=atol(SoftLimitPT);