1

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

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

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

3 回答 3

2

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

于 2010-10-18T22:37:31.143 回答
2

标准案例

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

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

“枚举”案例

.ini以上适用于从文件中检索一个字符串值的标准情况。如果您改为NULL作为lpAppNameorlpKeyName参数传递,以便枚举所有可用值,并且您提供的缓冲区太小,则返回值将比缓冲区大小小2 。

分配策略

您将不得不动态分配缓冲区。因此,您可能会根据需要使用std::auto_ptrorstd::unique_ptr或 a 。如果您事先不知道字符串有多大,我建议您从 250秒开始,每次发现缓冲区太小时将大小加倍。在实践中,我敢打赌 250 在 99.9999% 的情况下就足够了。std::vector<_TCHAR>resize()_TCHAR

备择方案

XML 文件存储在%APPDATA%; %APPDATA%存储在注册表下的 JSON 文件...</p>

于 2010-10-18T22:54:13.917 回答
2

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

如果您使用堆栈上的内存,那么精确并不重要。内存分配非常快(大约比堆上快 100 或 1000 倍),从当前函数返回后,内存将自动释放。所以你可以定义一个变量

TCHAR szBuffer[16384];

堆栈上的 16K 几乎没有。然后你可以GetPrivateProfileStringszBufferas调用lpReturnedString。该函数GetPrivateProfileString返回复制到缓冲区的字符数。如果该值小于 16K-1,那么您将知道确切的缓冲区大小。您现在可以在堆上分配大小的内存块并将数据复制szBuffer到块中。如果返回值GetPrivateProfileString等于 16K-1,那么你的缓冲区太小了。在这种情况下,您可以实现缓冲区大小的任何加倍(并且现在使用堆的缓冲区),但我更愿意将其解释为ini-file 中的错误。全部真实我以前使用的ini文件很小。条目的大小大多小于 260 个字符。所以条目大小为 16K 你可以解释为错误。

顺便说一句,您可以根据GetFileSizeEx验证 INI 文件的大小。条目大小必须小于 INI 文件的大小。

您必须在程序中包含对 INI 大小的一些限制。如果条目大小以 GB 为单位,那么您可能会收到问题。为什么不限制允许条目的大小,例如 16K?

于 2010-10-19T01:10:30.540 回答