2013-10-08 70 views
0

根據this answer的相關問題,我試圖編寫一個方法將標準字符串轉換爲一個寬字符串,然後我可以將其轉換爲wchar_t *。wchar_t和c_str字符串轉換出現意外的結果

爲什麼不是創建wchar_t *等價物的兩種不同方式? (我已經顯示了我的調試器給我的值)。

TEST_METHOD(TestingAssertsWithGetWideString) 
{ 
    std::wstring wString1 = GetWideString("me"); 
    const wchar_t* wchar1 = wString1.c_str(); // wchar1 = "me" 
    const wchar_t* wchar2 = GetWideString("me").c_str(); // wchar2 = "ﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮ@" (Why?!) 
} 

其中GetWideString定義如下:

inline const std::wstring GetWideString(const std::string &str) 
{ 
    std::wstring wstr; 
    wstr.assign(str.begin(), str.end()); 

    return wstr; 
}; 

注:以下也不起作用。

const wchar_t* wchar2 = GetWChar("me"); 

const wchar_t *GetWChar(const std::string &str) 
{ 
    std::wstring wstr; 
    wstr.assign(str.begin(), str.end()); 

    return wstr.c_str(); 
}; 
+1

'//爲什麼這一工作並不' - 你有一個指針到一個臨時緩衝區。 – chris

回答

2

每次您撥打GetWideString()時,都會創建一個新的std::wstring,它具有新分配的內存緩衝區。您正在比較指向不同內存塊的指針(假設Assert::AreEqual()只是比較指向的內存塊的指針指針本身而不是內容)。

更新const wchar_t* wchar2 = GetWideString("me").c_str();不起作用,因爲GetWideString()返回臨時std::wstring是超出範圍,並得到儘快語句執行完畢釋放。因此,您正在獲取一個指向臨時內存塊的指針,然後在該內存被釋放之前將該指針懸空,然後您可以使用該指針進行任何操作。

另外,const wchar_t* wchar2 = GetWChar("me");不應該編譯。 GetWChar()返回std::wstring,它不會實現隱式轉換爲wchar_t*。您必須使用c_str()方法從std::wstring獲得wchar_t*

+0

好點,但我編輯了我的問題,以澄清我在找什麼。 – sgryzko

+0

感謝您的解釋。我沒有意識到返回的std :: wstring超出了範圍。 (PS我已經修復了你說的不應該編譯的部分,這是一個錯字)。 – sgryzko

+0

我明白'std :: string'使用'char'嗎?作爲一個老式的程序員,他正試圖學習新的做事方式,因此我有足夠的麻煩來找到學習'std:string'的理由。不要告訴我,它不支持開箱即用的寬字符。 –

1

因爲兩個指針不相等。 A wchar_t *不是String,所以你得到generic AreEqual

+0

好點,但我編輯了我的問題,以澄清我在找什麼。 – sgryzko

0

std::wstring包含wchar_t類型的寬字符。 std::string包含char類型的字符。對於存儲在std::string中的特殊字符,正在使用多字節編碼,即某些字符在該字符串中由2個字符表示。因此,調用這些簡單的assign並不容易。

要「廣」字符串和多字節字符串之間進行轉換,可以使用以下助手(僅Windows):?!

// multi byte to wide char: 
std::wstring s2ws(const std::string& str) 
{ 
    int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0); 
    std::wstring wstrTo(size_needed, 0); 
    MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed); 
    return wstrTo; 
} 

// wide char to multi byte: 
std::string ws2s(const std::wstring& wstr) 
{ 
    int size_needed = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), int(wstr.length() + 1), 0, 0, 0, 0); 
    std::string strTo(size_needed, 0); 
    WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), int(wstr.length() + 1), &strTo[0], size_needed, 0, 0); 
    return strTo; 
} 
+0

假設沒有任何特殊字符,我的簡單分配會按預期工作是正確的嗎? – sgryzko