开发者

converting narrow string to wide string

How can i convert a narrow string to a wide string ?

I have tried this method :

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 *'

But i get errors as listed above.

Why do i get these errors ? How can i fix them ?

Is there any other method of directly converting a narrow开发者_如何学编程 string to a wide string ?


If the source is ASCII encoded, you can just do this:

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


You should do this :

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;
}

This expects the std::string to be UTF-8 (CP_UTF8), when you have another encoding replace the codepage.

Another way could be :

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;
}


I found this while googling the problem. I have pasted the code for reference. Author of this post is 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());


ATL (non-express editions of Visual Studio) has a couple useful class types which can convert the strings plainly. You can use the constructor directly, if you do not need to hold onto the string.

#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


Here are two functions that can be used: mbstowcs_s and wcstombs_s.

mbstowcs_s: Converts a sequence of multibyte characters to a corresponding sequence of wide characters. wcstombs_s: Converts a sequence of wide characters to a corresponding sequence of multibyte characters.

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 

);

See http://msdn.microsoft.com/en-us/library/eyktyxsx.aspx and http://msdn.microsoft.com/en-us/library/s7wzt4be.aspx.


The Windows API provides routines for doing this: WideCharToMultiByte() and MultiByteToWideChar(). However, they are a pain to use. Each conversion requires two calls to the routines and you have to look after allocating/freeing memory and making sure the strings are correctly terminated. You need a wrapper!

I have a convenient C++ wrapper on my blog, here, which you are welcome to use.


The original question of this thread was: "How can i convert a narrow string to a wide string?"

However, from the example code given in the question, there seems to be no conversion necessary. Rather, there is a compiler error due to the newer compilers deprecating something that used to be okay. Here is what I think is going on:

    // 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

The c_str() seems to be treated the same as a literal, and is considered a constant (const). You could use a cast. But preferable is to add const.

The best answer I have seen for converting between wide and narrow strings is to use std::wstringstream. And this is one of the answers given to C++ Convert string (or char*) to wstring (or wchar_t*)

You can convert most anything to and from strings and wide strings using stringstream and wstringstream.


This article published on the MSDN Magazine 2016 September issue discusses the conversion in details using Win32 APIs.

Note that using MultiByteToWideChar() is much faster than using the std:: stuff on Windows.


Use mbtowc():

string myName;
wchar_t wstr[BUFFER_SIZE];

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜