2016-02-26 208 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 )操作並將其刪除。 –