使用wchar_t和c_str字符串转换时出现意外结果

时间:2013-10-08 00:12:03

标签: c++ string type-conversion wstring string-conversion

基于this answer相关问题,我尝试编写一个方法,将标准字符串转换为宽字符串,然后我可以将其转换为wchar_t *。

为什么不是两种不同的方法来创建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();
};

3 个答案:

答案 0 :(得分: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()方法从wchar_t*获取std::wstring

答案 1 :(得分:1)

因为两个指针不相等。 wchar_t *不是String,因此您获得了generic AreEqual

答案 2 :(得分: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;
}