【问题标题】:GetPrivateProfileString - c++ class - return string - memory pre calculationGetPrivateProfileString - c++ 类 - 返回字符串 - 内存预计算
【发布时间】:2011-04-27 05:02:02
【问题描述】:

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

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

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

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

    • 哦,我明白为什么它不像普通的 Windows API 函数了。这是老式的,回到 Win16 时代。这应该只由旧代码使用,如果您正在编写新东西,请寻找更现代的 API。
    • 对更现代的 API 有什么建议吗?
    • 不,我已经很多年没有做过 Windows API 编程了,所以我不知道他们现在为 INI 提供了什么。查看 MSDN,他们可能有一些东西,
    • @user164054 - 如果您可以选择,请将应用程序数据从 ,INI 文件迁移到注册表。
    【解决方案2】:

    标准箱

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

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

    “枚举”案例

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

    分配策略

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

    替代品

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

    【讨论】:

      【解决方案3】:

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

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

      TCHAR szBuffer[16384];
      

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-10
        • 1970-01-01
        • 2023-02-25
        • 1970-01-01
        • 2012-05-03
        • 1970-01-01
        相关资源
        最近更新 更多