2023年12月25日发(作者:)

/chinabinlang/article/details/6424885

WriteProfileString 函数:

背景:

调用了WriteProfileString, 却不知道该配置信息到底是注册表中,还是在INI文件中. 经过在网上查询, 在windows的目录下找到与程序名同名的INI文件.

原因:

1/调试跟踪到CWinApp::WriteProfileString中间,发现了这个函数:

return ::WritePrivateProfileString(lpszSection, lpszEntry,

lpszValue,m_pszProfileName);

然后根据m_pszProfileName的名字(因为我的应用程序名字为)查找,最后在C:/WINDOWS下查找到了的文件,打开正好;

2/ 事实上WriteProfileString可以往注册表写也可往INI文件写,关键是SetRegistryKey,如果执行了 SetRegistryKey,那么就会写往注册表,如果没有,就会写往INI文件,请看 MSDN 说明:

3/如果你要写文件,用WritePrivateProfileString吧,不要用那个WriteProfileString.

/s/blog_

WritePrivateProfileString 函数:

GetPrivateProfileString函数对应;

WritePrivateProfileStruct 函数

#include

#include

using namespace std;

struct Data

{

int n;

char c[260];

};

int main()

{

Data d1,d2;

d1.n=10;

strcpy(d1.c,"hello");

WritePrivateProfileStruct( "MI", "DATA", &d1, sizeof(Data), "f:" );//mark

GetPrivateProfileStruct( "MI", "DATA", &d2, sizeof(Data), "f:" );//mark

cout<

return 0;

}

转一篇文章:

VC操作INI文件

INI文件简介

在我们写程序时,总有一些配置信息需要保存下来,以便在下一次启动程序完成初始化,这实际上是一种类持久化。将一些信息写入INI文件(initialization file)中,可完成简单的持久化支持。

Windows提供了API接口用于操作INI文件,其支持的INI文件格式一般如下:

===============================

[Section1]

Key11=value11

Key12=value12

[Section2]

Key21=value21

Key22=value22

...

[SectionN]

KeyN1=valueN1

KeyN2=valueN2

===============================

一般一个INI文件可有N个节,每节可有n个键名及值对应,每个键名及其值以等式形式占一行。

一般键的名称可任取,不过建议用有意义的字符及词构成。值一般可为整数和字符串,其它类型要进行转换。

常见的系统配置文件:

C:/

C:/WINDOWS/

C:/WINDOWS/

C:/WINDOWS/

C:/WINDOWS/Resources/Themes/Windows

注意,字符串存贮在INI文件中时没有引号;key和value之间的等号前后不容空格;注释以分号“;”开头。

VC中操作INI文件的API

(1)操作系统配置文件的函数:

函数名 功能

GetProfileSection 读取中指定节lpAppName中所有键名及其值。lpReturnedString字符串形式如下:

Key1=Value1/0Key2=Value2/0…KeyN=ValueN/0/0

GetProfileString 读取中指定节lpAppName中键名为lpKeyName对应变量的字符串值。

GetProfileInt 读取中指定节lpAppName中键名为lpKeyName对应变量的整数值。

WriteProfileSection

写(替换)中指定节lpAppName中的键值。

lpString字符串形式同GetProfileSection中的lpReturnedString。

WriteProfileString 写(替换)中指定节lpAppName中键名为lpKeyName对应变量的字符串值。

(2)操作用户自定义配置文件()的函数:

函数名 功能

GetPrivateProfileSectionNames 读取lpFileName指定的配置文件中所有的节名。lpszReturnBuffer字符串形式如下:

Section1/0Section2/0…SectionN/0/0

GetPrivateProfileSection 同GetProfileSection。

GetPrivateProfileString 同GetProfileString。

GetPrivateProfileInt 同GetProfileInt

GetPrivateProfileStruct 须同WritePrivateProfileStruct配套使用。

WritePrivateProfileSection 同WriteProfileSection

WritePrivateProfileString 同WriteProfileString

WritePrivateProfileStruct 不常用。

注意:

(1)使用得最频繁的是 GetPrivateProfileString 和 WritePrivateProfileString,没有WriteProfileInt/WritePrivateProfileInt函数。

(2)Get系列读取节键值,如果文件路径有误或节键名不对则返回设定的默认值。

(3)访存自定义配置文件时,文件路径lpFileName必须完整,文件名前面的各级目录必须存在。如果lpFileName文件路径不存在,则函数返回FALSE,GetLastError() = ERROR_PATH_NOT_FOUND。如果路径正确,但是文件不存在,则该函数将先创建该文件。如果路径及文件存在,则在现有ini文件基础上进行读写。

如果 lpFileName 只指定文件名而没有路径的话,调用API将会去 Windows 的安装目录去查找而不会在当前目录查找。

(4)要对调用API的模块(exe)所在目录下进行配置文件操作,可使用形如“.//”的相对路径,注意转义符。

(5)调用WritePrivateProfileSection,若参数三 lpString为NULL,则可将对应section的全部内容清空;调用WritePrivateProfileString,若参数三 lpString为NULL,则可将对应key删除。

跨平台配置文件

INI文件本质是对文件和字符串的处理,因此在跨平台项目中的配置文件可以基于中的标C文件FILE,然后实现像类似以上对节([Section])、键(Key)和值(Value)的字符串读写功能。

鉴于XML的树形描述层次结构性清晰,现在很多软件都大面积使用XML文件进行配置,如QQ的全局配置文件C:/Program

Files/Tencent/QQ/。java程序的配置文件基本都使用XML格式,C++中并没有操作XML文件的标准库。

在C/C++程序中要使用XML做为配置文件,涉及到XML的解析。

Windows平台可使用MsXml对XML进行解析,参考《MsXml创建和解析XML示例》,跨平台可以考虑自己实现,或使用C++ BOOST正则表达式,或选择Free C or C++ XML Parser Libraries,如XmlParser、TinyXML、CMarkup、libxml等。

CIniFile类

以下提供对Windows操作INI文件的API的简单封装类CIniFile。

[cpp] view plaincopyprint?

1. // IniFile.h

2. #ifndef __INIFILE_H__

3. #define __INIFILE_H__

4.

5. class CIniFile

6. {

7. public:

8. CIniFile();

9. CIniFile(LPCTSTR szFileName);

10. virtual ~CIniFile();

11.

12. public:

13. // Attributes

14. void SetFileName(LPCTSTR szFileName);

15.

16. public:

17. // Operations

18. BOOL SetProfileInt(LPCTSTR lpszSectionName, LPCTSTR lpszKeyName, int nKeyValue);

19. BOOL SetProfileString(LPCTSTR lpszSectionName, LPCTSTR lpszKeyName, LPCTSTR lpszKeyValue);

20.

21. DWORD GetProfileSectionNames(CStringArray& strArray); // 返回section数量

22.

23. int GetProfileInt(LPCTSTR lpszSectionName, LPCTSTR lpszKeyName);

24. DWORD GetProfileString(LPCTSTR lpszSectionName, LPCTSTR lpszKeyName, CString& szKeyValue);

25.

26. BOOL DeleteSection(LPCTSTR lpszSectionName);

27. BOOL DeleteKey(LPCTSTR lpszSectionName, LPCTSTR

lpszKeyName);

28.

29. private:

30. CString m_szFileName; // .//, 如果该文件不存在,则exe第一次试图Write时将创建该文件

31.

32. UINT m_unMaxSection; // 最多支持的section数(256)

33. UINT m_unSectionNameMaxSize; // section名称长度,这里设为32(Null-terminated)

34.

35. void Init();

36. };

37.

38. #endif

39.

40. //

41. #include "IniFile.h"

42.

43. void CIniFile::Init()

44. {

45. m_unMaxSection = 512;

46. m_unSectionNameMaxSize = 33; // 32位UID串

47. }

48.

49. CIniFile::CIniFile()

50. {

51. Init();

52. }

53.

54. CIniFile::CIniFile(LPCTSTR szFileName)

55. {

56. // (1) 绝对路径,需检验路径是否存在

57. // (2) 以"./"开头,则需检验后续路径是否存在

58. // (3) 以"../"开头,则涉及相对路径的解析

59.

60. Init();

61.

62. // 相对路径

63. m_(".//%s", szFileName);

64. }

65.

66. CIniFile::~CIniFile()

67. {

68.

69. }

70.

71. void CIniFile::SetFileName(LPCTSTR szFileName)

72. {

73. m_(".//%s", szFileName);

74. }

75.

76. DWORD CIniFile::GetProfileSectionNames(CStringArray &strArray)

77. {

78. int nAllSectionNamesMaxSize = m_unMaxSection*m_unSectionNameMaxSize+1;

79. char *pszSectionNames = new char[nAllSectionNamesMaxSize];

80. DWORD dwCopied = 0;

81. dwCopied = ::GetPrivateProfileSectionNames(pszSectionNames, nAllSectionNamesMaxSize, m_szFileName);

82.

83. All();

84.

85. char *pSection = pszSectionNames;

86. do

87. {

88. CString szSection(pSection);

89. if (gth() < 1)

90. {

91. delete[] pszSectionNames;

92. return dwCopied;

93. }

94. (szSection);

95.

96. pSection = pSection + gth() + 1; // next section name

97. } while (pSection && pSection

98.

99. delete[] pszSectionNames;

100. return dwCopied;

101. }

102.

103. DWORD CIniFile::GetProfileString(LPCTSTR lpszSectionName, LPCTSTR lpszKeyName, CString& szKeyValue)

104. {

105. DWORD dwCopied = 0;

106. dwCopied = ::GetPrivateProfileString(lpszSectionName, lpszKeyName, "",

107. fer(MAX_PATH), MAX_PATH, m_szFileName);

108. eBuffer();

109.

110. return dwCopied;

111. }

112.

113. int CIniFile::GetProfileInt(LPCTSTR lpszSectionName, LPCTSTR lpszKeyName)

114. {

115. int nKeyValue = ::GetPrivateProfileInt(lpszSectionName, lpszKeyName, 0, m_szFileName);

116.

117. return nKeyValue;

118. }

119.

120. BOOL CIniFile::SetProfileString(LPCTSTR lpszSectionName, LPCTSTR lpszKeyName, LPCTSTR lpszKeyValue)

121. {

122. return ::WritePrivateProfileString(lpszSectionName, lps

zKeyName, lpszKeyValue, m_szFileName);

123. }

124.

125. BOOL CIniFile::SetProfileInt(LPCTSTR lpszSectionName, LPCTSTR lpszKeyName, int nKeyValue)

126. {

127. CString szKeyValue;

128. ("%d", nKeyValue);

129.

130. return ::WritePrivateProfileString(lpszSectionName, lpszKeyName, szKeyValue, m_szFileName);

131. }

132.

133. BOOL CIniFile::DeleteSection(LPCTSTR lpszSectionName)

134. {

135. return ::WritePrivateProfileSection(lpszSectionName, NULL, m_szFileName);

136. }

137.

138. BOOL CIniFile::DeleteKey(LPCTSTR lpszSectionName, LPCTSTR lpszKeyName)

139. {

140. return ::WritePrivateProfileString(lpszSectionName, lpszKeyName, NULL, m_szFileName);

141. }

参考:

《在VC++中读写INI文件》

《VC INI文件读写》

《用VC++操作INI文件》

《INI操作类》

《INI文件查看器》

《C++中的XML配置文件编程经验》