C++ - 在没有缓冲区的情况下使用 GetPrivateProfileString

C++ - Using GetPrivateProfileString without buffer

我正在使用 GetPrivateProfileStringA 从 .ini 文件中读取一些内容。我还有一些其他的 class,我在其中保存一些东西以及一个字符串数组。我必须像这样使用它才能将正确的字符串放入 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];

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

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

C++ '98 说:"A program shall not alter any of the characters in this sequence." 然而,符合较新标准的实现可能更愿意忍受猴子生意:resize() 使缓冲区足够大,然后使用 &foo[0] to get a char * that isn't const (or just const_cast away the protection on data()),让 GetPrivateProfileStringA 写入缓冲区,然后在到达的 '[=11=]' 处截断 std::string。但是,这仍然不允许您将 std::string 直接传递给需要缓冲区指针的函数,因为它们不是同一件事 - 它只是让您有机会避免从缓冲区。