基于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();
};
答案 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;
}