9

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 ?

Mr.C64
  • 41,637
  • 14
  • 86
  • 162
saplingPro
  • 20,769
  • 53
  • 137
  • 195

9 Answers9

12

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

wstring printerName;
printerName.assign( myName.begin(), myName.end() );
Blazes
  • 4,721
  • 2
  • 22
  • 29
  • 1
    By far the simplest way. I'm surprised this doesn't have more up votes. – Bronco Sep 20 '17 at 18:13
  • 1
    *"I'm surprised this doesn't have more upvotes."* I guess because it fails in the (perhaps) most common case, i.e. if `myName` is UTF-8. – Sz. Jan 07 '22 at 00:43
11

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;
}
Kshitij Banerjee
  • 1,678
  • 1
  • 19
  • 35
Christopher
  • 8,912
  • 3
  • 33
  • 38
  • 1
    It converts a narrow std::string (here UTF-8) to a std::wstring by using the MultiByteToWideChar Win32 API call. – Christopher Jul 14 '11 at 12:22
  • 1
    To pick nits: It would be better to pass a reference to the output string. Then you are not depending on the compiler to optimize away the copy on return, and will not get stack overflow if someone uses the routine to convert a book length manuscript. – ravenspoint Jul 14 '11 at 12:30
  • Production quality code should handle error cases as well (e.g. throwing exceptions). [This MSDN Magazine article](https://msdn.microsoft.com/en-us/magazine/mt763237.aspx), a link to which I provided in an answer here, describes the process in more details. – Mr.C64 Oct 06 '16 at 21:05
3

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
Alex
  • 31
  • 1
3

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.

eddyq
  • 879
  • 1
  • 13
  • 25
3

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());
Ólafur Waage
  • 68,817
  • 22
  • 142
  • 198
  • 3
    @grassPro: `L` works only with constatnt strings like `L"Hello";`. Second error is self-explanatory, `c_str()` returns `const wchar_t*` which you can not convert to `wchar_t*`. – Naveen Jul 14 '11 at 10:19
2

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.

ravenspoint
  • 19,093
  • 6
  • 57
  • 103
1

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.

Community
  • 1
  • 1
Indinfer
  • 532
  • 5
  • 4
0

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.

Mr.C64
  • 41,637
  • 14
  • 86
  • 162
0

Use mbtowc():

string myName;
wchar_t wstr[BUFFER_SIZE];

getline( cin , myName );
mbtowc(wstr, myName, BUFFER_SIZE);
Simon Rigét
  • 2,757
  • 5
  • 30
  • 33
  • I'm calling mbtowc() and getting garbage but MultiByteToWideChar is fine. Any ideas? BAD: mbtowc( wczBuf, szBuf, strlen( szBuf ) ); GOOD: MultiByteToWideChar( CP_UTF8, 0, szBuf, -1, wczBuf, 4096 ); – Swiss Frank Apr 29 '19 at 15:48