那麼什麼是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();
}
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);