【问题标题】:C++ - Using GetPrivateProfileString without bufferC++ - 使用没有缓冲区的 GetPrivateProfileString
【发布时间】:2016-02-26 00:07:55
【问题描述】:

我正在使用 GetPrivateProfileStringA 从 .ini 文件中读取一些内容。我有一些其他的类,我将东西与字符串数组一起保存。我必须像这样使用它来将正确的字符串放入 ControlAlt 数组:

char buffer[24];
GetPrivateProfileStringA("CONTROLS",
    "ShiftUpAlt",
    "LeftThumb",
    buffer,
    (DWORD)24,
    "./Gears.ini");
scriptControl->ControlAlt[ScriptControls::ControlType::ShiftUp] = buffer;

我试过直接放进去,像这样:

GetPrivateProfileStringA("CONTROLS",
    "ShiftUpAlt",
    "LeftThumb",
    (LPSTR)scriptControl->ControlAlt[ScriptControls::ControlType::ShiftUp],
    (DWORD)24,
    "./Gears.ini");

但是 ControlAlt 中的值是一个 LPSTR,稍后在将其与正确的字符串进行比较时会产生复杂性。有没有办法不为此使用缓冲区?

ControlAlt 定义为std::string ControlAlt[SIZEOF_ControlType];

【问题讨论】:

  • scriptControl->ControlAlt[ScriptControls::ControlType::ShiftUp]的类型是什么?
  • 你明白指针和数组的区别吗?
  • ControlAlt[] 是一个字符串数组。另外,指针呢? scriptControl 是一个指针,而 ControlAlt 只是一个字符串数组。
  • 你的意思是std::string的数组吗?
  • 是的:std::string ControlAlt[SIZEOF_ControlType];

标签: c++ string lpstr


【解决方案1】:

GetPrivateProfileStringA 需要一个缓冲区来写入经典的 C 风格 '\0' 终止的字符串,而 std::string 不是这样的缓冲区,尽管如您所见,C 风格的字符串可以转换为std::string.

更具体地说,GetPrivateProfileStringA 期望 char *(在 Windows API 术语中为LPSTR)指向一个可写缓冲区和该缓冲区的长度。 std::string 不提供这个 - 充其量,它提供了 c_str() 访问器,它返回 const char *(Windows API 术语中的 LPCSTR) - 一个指向只读缓冲区的指针。缓冲区数据的const-ness 很好地表明修改它是一个坏主意,而且很可能会导致未定义的行为。

C++ '98 说:“程序不得更改此序列中的任何字符。”然而,符合新标准的实现可能更愿意忍受猴子业务:resize() 使缓冲区足够大,然后使用&foo[0] 获得不是constchar *(或者只是const_cast 去掉data() 上的保护),让GetPrivateProfileStringA 写入缓冲区,然后将std::string 截断到'\0' 的任何位置。但是,这仍然不允许您将 std::string 直接传递给需要缓冲区指针的函数,因为它们不是同一件事 - 它只是让您有机会避免从缓冲区中复制字符串一次。

【讨论】:

  • 啊,我现在明白为什么了,谢谢你的解释。我想我会坚持使用缓冲区的解决方案,因为走我最初想走的路似乎很不安全?至少,这是我从this 了解到的。我想我可以重新使用该缓冲区而不清除它?或者我应该将整个缓冲区设置为 \0 以确保它不包含旧数据?
  • 您当然可以重复使用它。缓冲区中的旧数据或其他垃圾理论上不应该成为问题,因为转换时除了尾随 '\0' 之外的任何内容都被视为字符串值的一部分,并且 GetPrivateProfileString 总是写入尾随 '\0'
  • 如果处理敏感信息,建议事后清除缓冲区,但使用SecureZeroMemory 而不是memsetbzero 或您自己的循环。这是因为如果优化编译器注意到内存在被覆盖后被释放而不被读取,它很可能会认为覆盖是无意义的"dead store" 操作并将其删除。
  • 那就放心了。它不包含敏感数据,所以我可以删除更多内容。
猜你喜欢
  • 2012-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多