将窄字符串转换为宽字符串

时间:2011-07-14 10:11:08

标签: c++ string visual-c++ unicode

如何将狭窄的string转换为宽string

我尝试过这种方法:

string myName;
getline( cin , myName );
wstring printerName( L(myName) );  // error C3861: 'L': identifier not found
wchar_t* WprinterName = printerName.c_str(); // error C2440: 'initializing' : cannot convert from 'const wchar_t *' to 'wchar_t *'

但是我得到了上面列出的错误。

为什么我会收到这些错误?我该如何解决它们?

是否有其他方法可以将narrow字符串直接转换为wide字符串?

9 个答案:

答案 0 :(得分:7)

你应该这样做:

inline std::wstring convert( const std::string& as )
{
            // deal with trivial case of empty string
    if( as.empty() )    return std::wstring();

            // determine required length of new string
    size_t reqLength = ::MultiByteToWideChar( CP_UTF8, 0, as.c_str(), (int)as.length(), 0, 0 );

            // construct new string of required length
    std::wstring ret( reqLength, L'\0' );

            // convert old string to new string
    ::MultiByteToWideChar( CP_UTF8, 0, as.c_str(), (int)as.length(), &ret[0], (int)ret.length() );

            // return new string ( compiler should optimize this away )
    return ret;
}

当你有另一个编码替换代码页时,这需要std :: string为UTF-8(CP_UTF8)。

另一种方式可能是:

inline std::wstring convert( const std::string& as )
{
    wchar_t* buf = new wchar_t[as.size() * 2 + 2];
    swprintf( buf, L"%S", as.c_str() );
    std::wstring rval = buf;
    delete[] buf;
    return rval;
}

答案 1 :(得分:6)

如果源是ASCII编码的,您可以这样做:

wstring printerName;
printerName.assign( myName.begin(), myName.end() );

答案 2 :(得分:3)

我在搜索问题时找到了this。我已粘贴代码以供参考。这篇文章的作者是Paul McKenzie。

std::string str = "Hello";
std::wstring str2(str.length(), L' '); // Make room for characters

// Copy string to wstring.
std::copy(str.begin(), str.end(), str2.begin());

答案 3 :(得分:3)

ATL(Visual Studio的非快速版本)有一些有用的类类型,可以清楚地转换字符串。如果您不需要保留字符串,则可以直接使用构造函数。

#include <atlbase.h>

std::wstring wideString(L"My wide string");
std::string narrowString("My not-so-wide string");

ATL::CW2A narrow(wideString.c_str()); // narrow is a narrow string
ATL::CA2W wide(asciiString.c_str()); // wide is a wide string

答案 4 :(得分:3)

以下是两个可以使用的函数:mbstowcs_s和wcstombs_s。

mbstowcs_s:将一系列多字节字符转换为相应的宽字符序列。 wcstombs_s:将一系列宽字符转换为相应的多字节字符序列。

errno_t wcstombs_s(
   size_t *pReturnValue,
   char *mbstr,
   size_t sizeInBytes,
   const wchar_t *wcstr,
   size_t count 
);

errno_t mbstowcs_s(
   size_t *pReturnValue,
   wchar_t *wcstr,
   size_t sizeInWords,
   const char *mbstr,
   size_t count 

);

请参阅http://msdn.microsoft.com/en-us/library/eyktyxsx.aspxhttp://msdn.microsoft.com/en-us/library/s7wzt4be.aspx

答案 5 :(得分:1)

Windows API提供了执行此操作的例程:WideCharToMultiByte()和MultiByteToWideChar()。但是,使用它们很痛苦。每次转换都需要对例程进行两次调用,并且必须考虑分配/释放内存并确保字符串正确终止。你需要一个包装器!

我的博客here上有一个方便的C ++包装器,欢迎您使用。

答案 6 :(得分:1)

这个主题的原始问题是:“我如何将一个窄字符串转换为一个宽字符串?”

但是,根据问题中给出的示例代码,似乎没有必要进行转换。相反,由于较新的编译器弃用了过去没问题的东西,因此存在编译器错误。以下是我的想法:

    // wchar_t* wstr = L"A wide string";     // Error: cannot convert from 'const wchar_t *' to 'wchar_t *'

wchar_t const* wstr = L"A wide string";             // okay
const wchar_t* wstr_equivalent = L"A wide string";  // also okay

c_str()似乎被视为与文字相同,并被视为常量(const)。你可以使用演员。但最好是添加const。

我看到在宽字符串和窄字符串之间进行转换的最佳答案是使用std :: wstringstream。这是给予C++ Convert string (or char*) to wstring (or wchar_t*)

的答案之一

您可以使用stringstream和wstringstream将大多数内容与字符串和宽字符串进行转换。

答案 7 :(得分:0)

发表于MSDN Magazine 2016年9月刊上的

This article使用Win32 API详细讨论了转换。

请注意,MultiByteToWideChar()使用much faster比使用Windows上的std :: stuff。

答案 8 :(得分:0)

使用 mbtowc ():

string myName;
wchar_t wstr[BUFFER_SIZE];

getline( cin , myName );
mbtowc(wstr, myName, BUFFER_SIZE);