2016-02-26 77 views
0

我使用GetPrivateProfileStringA从.ini文件读取一些内容。我有一些其他的类,我把它们和一个字符串数组一起存储。我不得不使用它像这样得到一个正确的串入ControlAlt数组:C++ - 使用不带缓冲区的GetPrivateProfileString

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];

+0

'scriptControl-> ControlAlt [ScriptControls :: ControlType :: ShiftUp]'的类型是什么? – MikeCAT

+0

你了解指针和数组的区别吗? – IInspectable

+0

ControlAlt []是一个字符串数组。另外,指针呢? scriptControl是一个指针,但ControlAlt只是一个字符串数组。 – ikt

回答

1

GetPrivateProfileStringA需要一个缓冲区来'\0'封端的串写经典C风格之中,并且std::string没有这样的缓冲,虽然你观察,一个C风格的字符串可以转换为std::string

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

C++ '98说:“程序不应该改变这个序列中的任何字符。”然而,符合新标准的实施很可能更愿意忍受猴子业务:resize()使缓冲区足够大,然后用&foo[0]获得char *不是const(或只是const_cast外出data()保护),让GetPrivateProfileStringA写入缓冲区,然后在'\0'处将std::string截断。尽管如此,这仍然不会让std::string直接传递给期望缓冲区指针的函数,因为它们不是同一个东西 - 它只是让您有机会避免将字符串从缓冲区中多复制一次。

+0

啊,我明白为什么了,谢谢你的解释。我想我会坚持使用缓冲区的解决方案,因为按照我最初想去的方式,似乎很不安全?至少,这是我从[this]中理解的(http://stackoverflow.com/questions/2880248/stdstring-resize-and-stdstring-length)。我想我可以重新使用该缓冲区而不清除它?或者我应该将整个缓冲区memset到\ 0以确保它不包含旧数据? – ikt

+0

你当然可以重复使用它。旧数据或缓冲区中的其他垃圾在理论上不应该成为问题,因为在转换时,没有超出尾部的''\ 0''被认为是字符串值的一部分,并且'GetPrivateProfileString'总是写入尾部的''\ 0' '。 –

+0

如果正在处理敏感信息,则建议清除缓冲区,但使用['SecureZeroMemory'](https://msdn.microsoft.com/en-us/library/windows/desktop/aa366877(v = vs.85) .aspx)而不是'memset','bzero'或你自己的循环。这是因为如果优化编译器注意到内存已被释放并且被覆盖后未被读取,则很可能认为覆盖是无意义的[“死亡存储”](https://en.wikipedia.org/wiki/Dead_store )操作并将其删除。 –