GetPrivateProfileString - c ++ class - 返回字符串 - 内存预计算

时间:2010-10-18 22:31:44

标签: c++ c winapi visual-c++ ini

GetPrivateProfileString中,lpReturnedString返回ini文件特定部分的键中存在的字符串值。

我的问题是,我将如何准确地知道需要分配多少内存,而不是在调用此函数之前分配一个大块。

DWORD WINAPI GetPrivateProfileString(
  __in   LPCTSTR lpAppName,
  __in   LPCTSTR lpKeyName,
  __in   LPCTSTR lpDefault,
  __out  LPTSTR lpReturnedString,
  __in   DWORD nSize,
  __in   LPCTSTR lpFileName
);

3 个答案:

答案 0 :(得分:2)

这很奇怪,通常Windows API函数允许您传入NULL并返回大小来制作缓冲区。这个功能似乎没有这样做。我会说你应该选择一个合理的尺寸。如果它不够大,请保持缓冲区大小加倍,直到得到它为止。

答案 1 :(得分:2)

标准案例

GetPrivateProfileString的返回值是复制到缓冲区的字符数,不包括空终止符。

因此,您可以从(例如)100 _TCHAR s的缓冲区开始并检查返回值。如果它是99,那么你要么完全猜到字符串的大小,要么(更有可能)你的缓冲区太小,所以放大它再试一次。

“枚举”案例

以上内容适用于从.ini文件中检索一个字符串值的标准情况。如果您将NULL作为lpAppNamelpKeyName参数传递,为了枚举所有可用值,并且您提供的缓冲区太小,返回值将为< em>两个小于缓冲区大小。

分配策略

您将不得不动态分配缓冲区。因此,您可以根据需要使用std::auto_ptrstd::unique_ptr,或std::vector<_TCHAR> resize()。如果您事先不知道字符串的大小,我建议从250 _TCHAR s开始,并在每次发现缓冲区太小时将大小加倍。在实践中,我认为250足够99.9999%的时间。

替代

存储在%APPDATA%下的XML文件; JSON文件存储在%APPDATA%下,注册表...

答案 2 :(得分:2)

根据您的问题,我认为您希望使用newmallocLocalAlloc或其他一些使用堆的函数在堆上分配内存。您可能希望尽可能少地使用堆内存。

如果您使用堆栈中的内存,那么完全没那么重要。内存分配非常快(比堆上快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来限制允许输入的大小?