在GetPrivateProfileString
中,lpReturnedString
返回ini文件特定部分的键中存在的字符串值。
我的问题是,我将如何准确地知道需要分配多少内存,而不是在调用此函数之前分配一个大块。
DWORD WINAPI GetPrivateProfileString(
__in LPCTSTR lpAppName,
__in LPCTSTR lpKeyName,
__in LPCTSTR lpDefault,
__out LPTSTR lpReturnedString,
__in DWORD nSize,
__in LPCTSTR lpFileName
);
答案 0 :(得分:2)
这很奇怪,通常Windows API函数允许您传入NULL并返回大小来制作缓冲区。这个功能似乎没有这样做。我会说你应该选择一个合理的尺寸。如果它不够大,请保持缓冲区大小加倍,直到得到它为止。
答案 1 :(得分:2)
GetPrivateProfileString
的返回值是复制到缓冲区的字符数,不包括空终止符。
因此,您可以从(例如)100 _TCHAR
s的缓冲区开始并检查返回值。如果它是99,那么你要么完全猜到字符串的大小,要么(更有可能)你的缓冲区太小,所以放大它再试一次。
以上内容适用于从.ini
文件中检索一个字符串值的标准情况。如果您将NULL
作为lpAppName
或lpKeyName
参数传递,为了枚举所有可用值,并且您提供的缓冲区太小,返回值将为< em>两个小于缓冲区大小。
您将不得不动态分配缓冲区。因此,您可以根据需要使用std::auto_ptr
或std::unique_ptr
,或std::vector<_TCHAR>
resize()
。如果您事先不知道字符串的大小,我建议从250 _TCHAR
s开始,并在每次发现缓冲区太小时将大小加倍。在实践中,我认为250足够99.9999%的时间。
存储在%APPDATA%
下的XML文件; JSON文件存储在%APPDATA%
下,注册表...
答案 2 :(得分:2)
根据您的问题,我认为您希望使用new
,malloc
,LocalAlloc
或其他一些使用堆的函数在堆上分配内存。您可能希望尽可能少地使用堆内存。
如果您使用堆栈中的内存,那么完全没那么重要。内存分配非常快(比堆上快100或1000倍),从当前函数返回后,内存将自动释放。所以你可以定义一个变量
TCHAR szBuffer[16384];
堆栈上的16K几乎没有。然后,您可以使用GetPrivateProfileString
作为szBuffer
来呼叫lpReturnedString
。函数GetPrivateProfileString
返回复制到缓冲区的字符数。如果该值小于16K-1,那么您将知道确切的缓冲区大小。您现在可以在堆上分配大小的内存块,并将数据从szBuffer
复制到块中。如果返回的GetPrivateProfileString
值等于16K-1,则缓冲区太小。在这种情况下,你可以实现任何加倍的缓冲区大小(现在使用堆的缓冲区),但我更喜欢将其解释为 ini文件中的错误。我以前用过的所有真实 ini文件都很小。条目的大小大多少于260个字符。因此,条目大小为16K,您可以将其解释为错误。
顺便说一句,您可以根据GetFileSizeEx验证INI文件的大小。条目大小必须小于INI文件的大小。
您必须在程序中包含对INI大小的一些限制。如果条目大小将以GB为单位进行测量,那么您可能会遇到问题。例如,为什么不用16K来限制允许输入的大小?