C++ Builder中的<inifiles.hpp>头文件在VC中有相应的头文件吗?
现在需要用到别人在C++ Buider下编的一个类,可是这个类包含了<inifiles.hpp>头文件,还有用TIniFile类 定义的一些变量,我怎么才能转换到MFC下使用?
MFC里有可替换<inifiles.hpp>的头文件 以及TIniFile类 吗?
[解决办法]
ini文件[wen jian](即Initialization file),这种类型[lei xing]的文件[wen jian]中通常存放的是一个程序的初始化[chu shi hua]信息[xin xi]。ini文件[wen jian]由若干个节(Section)组成,每个Section由若干键(Key)组成,每个Key可以赋相应的值。读写[du xie]ini文件[wen jian]实际上就是读写[du xie]某个的Section中相应的Key的值,而这只要借助几个函数[han shu]即可完成。
一、向ini文件[wen jian]中写入信息[xin xi]的函数[han shu]
1. 把信息[xin xi]写入系统[xi tong]的win.ini文件[wen jian]
BOOL WriteProfileString(
LPCTSTR lpAppName, // 节的名字,是一个以0结束的字符[zi fu]串[zi fu chuan]
LPCTSTR lpKeyName, // 键的名字,是一个以0结束的字符[zi fu]串[zi fu chuan]。若为NULL,则删除[shan chu]整个节
LPCTSTR lpString // 键的值,是一个以0结束的字符[zi fu]串[zi fu chuan]。若为NULL,则删除[shan chu]对应的键
)
2. 把信息[xin xi]写入自己定义的.ini文件[wen jian]
BOOL WritePrivateProfileString(
LPCTSTR lpAppName, // 同上
LPCTSTR lpKeyName, // 同上
LPCTSTR lpString, // 同上
LPCTSTR lpFileName // 要写入的文件[wen jian]的文件[wen jian]名[wen jian ming]。若该ini文件[wen jian]与程序在同一个目录下,也可使用相对
//路径[lu jing],否则需要给出绝度路径[lu jing]。
)
如:
::WriteProfileString("Test","id","xym");
//在win.ini中创建一个Test节,并在该节中创建一个键id,其值为xym
::WritePrivateProfileString("Test","id","xym","d:\\vc\\Ex1\\ex1.ini");
//在Ex1目录下的ex1.ini中创建一个Test节,并在该节中创建一个键id,其值为xym
//若Ex1.ini文件[wen jian]与读写[du xie]该文件[wen jian]的程序在同一个目录下,则上面语句[yu ju]也可写为:
::WritePrivateProfileString("Test","id","xym",".\\ex1.ini");
需要注意的是,C系列的语言[yu yan]中,转义[zhuan yi]字符[zi fu][zhuan yi zi fu]'\\'表示反斜线 '\'。另外,当使用相对路径[lu jing]时,\\前的.号不能丢掉了。
二、从ini文件[wen jian]中读取[du qu]数据[shu ju]的函数[han shu]
1、从系统[xi tong]的win.ini文件[wen jian]中读取[du qu]信息[xin xi]
(1) 读取[du qu]字符[zi fu]串[zi fu chuan]
DWORD GetProfileString(
LPCTSTR lpAppName, // 节名
LPCTSTR lpKeyName, // 键名,读取[du qu]该键的值
LPCTSTR lpDefault, // 若指定的键不存在,该值作为读取[du qu]的默认[mo ren]值
LPTSTR lpReturnedString, // 一个指向[zhi xiang]缓冲区的指针[zhi zhen],接收读取[du qu]的字符[zi fu]串[zi fu chuan]
DWORD nSize // 指定lpReturnedString指向[zhi xiang]的缓冲区的大小
)
如:
CString str;
::GetProfileString("Test","id","Error",str.GetBuffer(20),20);
(2) 读取[du qu]整数
UINT GetProfileInt(
LPCTSTR lpAppName, // 同上
LPCTSTR lpKeyName, // 同上
INT nDefault // 若指定的键名不存在,该值作为读取[du qu]的默认[mo ren]值
)
如使用以下语句[yu ju]写入了年龄信息[xin xi]:
::WriteProfileString("Test","age","25");
//在win.ini中创建一个Test节,并在该节中创建一个键age,其值为25
则可用以下语句[yu ju]读取[du qu]age键的值:
int age;
age=::GetProfileInt("Test","age",0);
2、从自己的ini文件[wen jian]中读取[du qu]信息[xin xi]
(1) 读取[du qu]字符[zi fu]串[zi fu chuan]
DWORD GetPrivateProfileString(
LPCTSTR lpAppName, // 同1(1)
LPCTSTR lpKeyName, // 同1(1)
LPCTSTR lpDefault, // 同1(1)
LPTSTR lpReturnedString, // 同1(1)
DWORD nSize, // 同1(1)
LPCTSTR lpFileName // 读取[du qu]信息[xin xi]的文件[wen jian]名[wen jian ming]。若该ini文件[wen jian]与程序在同一个目录下,也可使用相
//对路径[lu jing],否则需要给出绝度路径[lu jing]。
)
如:
CString str;
::GetPrivateProfileString("Test","id","Error",str.GetBuffer(20),20,".\\ex1.ini");
或:
::GetPrivateProfileString("Test","id","Error",str.GetBuffer(20),20,"d:\\vc \\Ex1\\ex1.ini");
(2) 读取[du qu]整数
UINT GetPrivateProfileInt(
LPCTSTR lpAppName, // 同上
LPCTSTR lpKeyName, // 同上
INT nDefault, // 若指定的键名不存在,该值作为读取[du qu]的默认[mo ren]值
LPCTSTR lpFileName // 同上
)
如使用以下语句[yu ju]写入了年龄信息[xin xi]:
::WritePrivateProfileString("Test","age","25",".\\ex1.ini");
//在ex1.ini中创建一个Test节,并在该节中创建一个键age,其值为25
则可用以下语句[yu ju]读取[du qu]age键的值:
int age;
age=::GetPrivateProfileInt("Test","age",0,".\\ex1.ini");
三、 删除[shan chu]键值或节
回顾一下WriteProfileString函数[han shu]的说明[shuo ming]
BOOL WriteProfileString(
LPCTSTR lpAppName, // 节的名字,是一个以0结束的字符[zi fu]串[zi fu chuan]
LPCTSTR lpKeyName, // 键的名字,是一个以0结束的字符[zi fu]串[zi fu chuan]。若为NULL,则删除[shan chu]整个节
LPCTSTR lpString // 键的值,是一个以0结束的字符[zi fu]串[zi fu chuan]。若为NULL,则删除[shan chu]对应的键
)
由此可见,要删除[shan chu]某个节,只需要将WriteProfileString第二个参数[can shu]设为NULL即可。而要删除[shan chu]某个键,则只需要将该函数[han shu]的第三个参数[can shu]设为 NULL即可。这是删除[shan chu]系统[xi tong]的win.ini中的节或键,类似的,要删除[shan chu]自己定义的ini文件[wen jian]中的节或键,也可做相同的操作。
如:
::WriteProfileString("Test",NULL,NULL); //删除[shan chu]win.ini中的Test节
::WriteProfileString("Test","id",NULL); //删除[shan chu]win.ini中的id键
::WritePrivateProfileString("Test",NULL,NULL,".\\ex1.ini"); //删除[shan chu]ex1.ini中的Test节
::WritePrivateProfileString("Test","id",NULL,".\\ex1.ini"); //删除[shan chu]ex1.ini中的id键
四、如何判断一个ini文件[wen jian]中有多少个节
要判断一个ini文件[wen jian]中有多少个节,最简单的办法就是将所有的节名都找出来,然后统计[tong ji]节名的个数。而要将所有的节名找出来,使用 GetPrivateProfileSectionNames函数[han shu]就可以了,其原型[yuan xing]如下:
DWORD GetPrivateProfileSectionNames(
LPTSTR lpszReturnBuffer, // 指向[zhi xiang]一个缓冲区,用来保存返回的所有节名
DWORD nSize, // 参数[can shu]lpszReturnBuffer的大小
LPCTSTR lpFileName // 文件[wen jian]名[wen jian ming],若该ini文件[wen jian]与程序在同一个目录下,
//也可使用相对路径[lu jing],否则需要给出绝度路径[lu jing]
)
下面的是用来统计[tong ji]一个ini文件[wen jian]中共有多少个节的函数[han shu],当然,如果需要同时找到每个节中的各个键及其值,根据找到节名就可以很容易的得到了。
/*统计[tong ji]共有多少个节
节名的分离方法[fang fa]:若chSectionNames数组[shu zu]的第一字符[zi fu]是'\0'字符[zi fu],则表明
有0个节。否则,从chSectionNames数组[shu zu]的第一个字符[zi fu]开始,顺序往后找,
直到找到一个'\0'字符[zi fu],若该字符[zi fu]的后继字符[zi fu]不是 '\0'字符[zi fu],则表明前
面的字符[zi fu]组成一个节名。若连续[lian xu]找到两个'\0'字符[zi fu],则统计[tong ji] 结束*/
int CTestDlg::CalcCount(void)
{
TCHAR chSectionNames[2048]={0}; //所有节名组成的字符[zi fu]数组[shu zu]
char * pSectionName; //保存找到的某个节名字符[zi fu]串[zi fu chuan]的首地址[di zhi]
int i; //i指向[zhi xiang]数组[shu zu]chSectionNames的某个位置[wei zhi],从0开始,顺序后移
int j=0; //j用来保存下一个节名字符[zi fu]串[zi fu chuan]的首地址[di zhi]相对于当前i的位置[wei zhi]偏移量[pian yi liang]
int count=0; //统计[tong ji]节的个数
//CString name;
//char id[20];
::GetPrivateProfileSectionNames(chSectionNames,2048,".\\ex1.ini");
for(i=0;i<2048;i++,j++)
{
if(chSectionNames[0]=='\0')
break; //如果第一个字符[zi fu]就是0,则说明[shuo ming]ini中一个节也没有
if(chSectionNames[i]=='\0')
{
pSectionName=&chSectionNames[i-j]; //找到一个0,则说明[shuo ming]从这个字符[zi fu]往前,减掉j个偏移量[pian yi liang],
//就是一个节名的首地址[di zhi]
j=-1; //找到一个节名后,j的值要还原[hai yuan],以统计[tong ji]下一个节名地址[di zhi]的偏移量[pian yi liang]
//赋成-1是因为节名字符[zi fu]串[zi fu chuan]的最后一个字符[zi fu]0是终止符,不能作为节名
//的一部分
/*::GetPrivateProfileString(pSectionName,"id","Error",id,20,".\\ex1.ini");
name.Format("%s",id);*/
//在获取节名的时候可以获取该节中键的值,前提[qian ti]是我们知道该节中有哪些键。
AfxMessageBox(pSectionName); //把找到的显示[xian shi]出来
if(chSectionNames[i+1]==0)
{
break; //当两个相邻的字符[zi fu]都是0时,则所有的节名都已找到,循环[xun huan]终止
}
}
}
return count;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
在VC程序中利用系统[xi tong]提供的 GetPrivateProfileString及WritePrivateProfileString函数[han shu]直接读写[du xie]系统[xi tong]配置[pei zhi][xi tong pei zhi]ini文件[wen jian](指定目录下的 Ini文件[wen jian])
假设在当前目录[dang qian mu lu]下有一个文件[wen jian]名[wen jian ming]为Tets.ini的文件[wen jian]
用于[yong yu]保存用户[yong hu]名[yong hu ming]和密码[mi ma]
文件[wen jian]格式如下:
[Section1]
Item1=huzhifeng
Item2=1234565
1.写INI文件[wen jian]
void CINI_File_TestDlg::OnButtonWrite()
{
// TODO: Add your control notification handler code here
CString strSection = "Section1";
CString strSectionKey = "Item1";
char strBuff[256];
CString strValue = _T("");
CString strFilePath;
strFilePath=GetCurrentDirectory(256,strBuff); //获取当前路径[lu jing]
strFilePath.Format("%s\\Test.ini",strBuff);
GetDlgItemText(IDC_EDIT_NAME,strValue); //获取文本[wen ben]框内容:即姓名
WritePrivateProfileString(strSection,strSectionKey,strValue,strFilePath); //写入ini文件[wen jian]中相应字段[zi duan]
strSectionKey="Item2";
GetDlgItemText(IDC_EDIT_PASSWORD,strValue); //获取文本[wen ben]框内容:即密码[mi ma]
WritePrivateProfileString(strSection,strSectionKey,strValue,strFilePath);
}
2.读INI文件[wen jian]内容
void CINI_File_TestDlg::OnButtonRead()
{
// TODO: Add your control notification handler code here
CString strSection = "Section1";
CString strSectionKey = "Item1";
char strBuff[256];
CString strValue = _T("");
CString strFilePath;
strFilePath=GetCurrentDirectory(256,strBuff); //获取当前路径[lu jing]
strFilePath.Format("%s\\Test.ini",strBuff);
GetPrivateProfileString(strSection,strSectionKey,NULL,strBuff,80,strFilePath); //读取[du qu]ini文件[wen jian]中相应字段[zi duan]的内容
strValue=strBuff;
SetDlgItemText(IDC_EDIT_NAME,strValue);
strSectionKey="Item2";
GetPrivateProfileString(strSection,strSectionKey,NULL,strBuff,80,strFilePath);
strValue=strBuff;
SetDlgItemText(IDC_EDIT_PASSWORD,strValue);
UpdateData(FALSE);
}