2013-10-08 35 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