string s = "おはよう";
wstring ws = FUNCTION(s, ws);

如何将s的内容分配给ws?

搜索谷歌并使用了一些技术,但他们不能分配确切的内容。内容被扭曲了。


当前回答

如果你正在使用Windows/Visual Studio并且需要将字符串转换为wstring,你可以使用:

#include <AtlBase.h>
#include <atlconv.h>
...
string s = "some string";
CA2W ca2w(s.c_str());
wstring w = ca2w;
printf("%s = %ls", s.c_str(), w.c_str());

与将wstring转换为string的过程相同(有时你需要指定一个代码页):

#include <AtlBase.h>
#include <atlconv.h>
...
wstring w = L"some wstring";
CW2A cw2a(w.c_str());
string s = cw2a;
printf("%s = %ls", s.c_str(), w.c_str());

您可以指定一个代码页,甚至UTF8(这在使用JNI/Java时非常好)。将std::wstring转换为utf8 std::string的标准方法显示在这个答案中。

// 
// using ATL
CA2W ca2w(str, CP_UTF8);

// 
// or the standard way taken from the answer above
#include <codecvt>
#include <string>

// convert UTF-8 string to wstring
std::wstring utf8_to_wstring (const std::string& str) {
    std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv;
    return myconv.from_bytes(str);
}

// convert wstring to UTF-8 string
std::string wstring_to_utf8 (const std::wstring& str) {
    std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv;
    return myconv.to_bytes(str);
}

如果你想了解更多关于代码页的知识,在Joel on Software上有一篇有趣的文章:每个软件开发人员绝对必须知道Unicode和字符集的绝对最小值。

这些CA2W(转换Ansi到宽=unicode)宏是ATL和MFC字符串转换宏的一部分,包括样本。

有时你需要禁用安全警告#4995',我不知道其他的解决方法(对我来说,当我在VS2012中为WindowsXp编译时就发生了这种情况)。

#pragma warning(push)
#pragma warning(disable: 4995)
#include <AtlBase.h>
#include <atlconv.h>
#pragma warning(pop)

编辑: 好吧,根据这篇文章,Joel的文章似乎是:“虽然很有趣,但它对实际的技术细节知之甚少”。文章:每个程序员绝对需要知道的关于编码和字符集来处理文本。

其他回答

根据我自己的测试(在windows 8上,vs2010) mbstowcs实际上可以破坏原始字符串,它只适用于ANSI代码页。If MultiByteToWideChar/WideCharToMultiByte也会导致字符串损坏-但他们倾向于用'?'问号,但mbstowcs往往会在遇到未知字符时停止,并在此时切断字符串。(我在芬兰语窗口上测试过越南字符)。

所以更喜欢Multi* windows api函数而不是模拟ansi C函数。

我还注意到,从一个代码页到另一个代码页编码字符串的最短方法不是使用MultiByteToWideChar/WideCharToMultiByte api函数调用,而是它们的模拟ATL宏:W2A / A2W。

所以如上所述的模拟函数听起来是这样的:

wstring utf8toUtf16(const string & str)
{
   USES_CONVERSION;
   _acp = CP_UTF8;
   return A2W( str.c_str() );
}

_acp在USES_CONVERSION宏中声明。

或者在执行旧数据到新数据的转换时,我经常错过的函数:

string ansi2utf8( const string& s )
{
   USES_CONVERSION;
   _acp = CP_ACP;
   wchar_t* pw = A2W( s.c_str() );

   _acp = CP_UTF8;
   return W2A( pw );
}

但请注意,这些宏使用大量的堆栈-不要为同一个函数使用for循环或递归循环-在使用W2A或A2W宏后-最好尽快返回,因此堆栈将从临时转换中释放出来。

您可以使用boost路径或std路径;这样就简单多了。 Boost路径更容易用于跨平台应用程序

#include <boost/filesystem/path.hpp>

namespace fs = boost::filesystem;

//s to w
std::string s = "xxx";
auto w = fs::path(s).wstring();

//w to s
std::wstring w = L"xxx";
auto s = fs::path(w).string();

如果你喜欢使用std:

#include <filesystem>
namespace fs = std::filesystem;

//The same

c++旧版本

#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;

//The same

代码内仍然实现了一个转换器,你不必解开细节。

这是一种将字符串,wstring和混合字符串常量组合到wstring的方法。使用wstringstream类。

这并不适用于多字节字符编码。这只是一种抛弃类型安全并将std::string中的7位字符扩展到std:wstring中每个字符的下7位的愚蠢方法。只有当你有一个7位ASCII字符串并且你需要调用一个需要宽字符串的API时,这才有用。

#include <sstream>

std::string narrow = "narrow";
std::wstring wide = L"wide";

std::wstringstream cls;
cls << " abc " << narrow.c_str() << L" def " << wide.c_str();
std::wstring total= cls.str();

String到wstring

std::wstring Str2Wstr(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;
}

从wstring到String

std::string Wstr2Str(const std::wstring& wstr)
{
    typedef std::codecvt_utf8<wchar_t> convert_typeX;
    std::wstring_convert<convert_typeX, wchar_t> converterX;
    return converterX.to_bytes(wstr);
}

对我来说,最简单又没有大开销的选择是:

包括:

#include <atlbase.h>
#include <atlconv.h>

转换:

char* whatever = "test1234";
std::wstring lwhatever = std::wstring(CA2W(std::string(whatever).c_str()));

如果需要:

lwhatever.c_str();