3

I'm new to C++ and I have this issue. I have a string called DATA_DIR that I need for format into a wstring.

string str = DATA_DIR; std::wstring temp(L"%s",str); 

Visual Studio tells me that there is no instance of constructor that matches with the argument list. Clearly, I'm doing something wrong.

I found this example online

std::wstring someText( L"hello world!" ); 

which apparently works (no compile errors). My question is, how do I get the string value stored in DATA_DIR into the wstring constructor as opposed to something arbitrary like "hello world"?

4
  • possible duplicate of How to convert std::string to LPCWSTR in C++ (Unicode) Commented Aug 14, 2013 at 23:58
  • Check out utf8everywhere.org and consider using the boost::nowide library provided on that page to convert string to wstring and back. Makes life much easier :) Commented Aug 15, 2013 at 0:21
  • 1
    What is the encoding of the text in the string? Usually either ISO/IEC 8859-1 (Which many incorrectly call "ASCII") or UTF-8. Commented Aug 15, 2013 at 0:28
  • Please see my edit below. My original code had a big mistake in it. Commented Aug 16, 2013 at 0:58

6 Answers 6

7

This is in reference to the most up-voted answer but I don't have enough "reputation" to just comment directly on the answer.

The name of the function in the solution "wstring_from_bytes" implies it is doing what the original poster wants, which is to get a wstring given a string, but the function is actually doing the opposite of what the original poster asked for and would more accurately be named "bytes_from_wstring".

To convert from string to wstring, the wstring_from_bytes function should use mbstowcs not wcstombs

#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <cstdlib> #include <string> std::wstring wstring_from_bytes(std::string const& str) { size_t requiredSize = 0; std::wstring answer; wchar_t *pWTempString = NULL; /* * Call the conversion function without the output buffer to get the required size * - Add one to leave room for the NULL terminator */ requiredSize = mbstowcs(NULL, str.c_str(), 0) + 1; /* Allocate the output string (Add one to leave room for the NULL terminator) */ pWTempString = (wchar_t *)malloc( requiredSize * sizeof( wchar_t )); if (pWTempString == NULL) { printf("Memory allocation failure.\n"); } else { // Call the conversion function with the output buffer size_t size = mbstowcs( pWTempString, str.c_str(), requiredSize); if (size == (size_t) (-1)) { printf("Couldn't convert string\n"); } else { answer = pWTempString; } } if (pWTempString != NULL) { delete[] pWTempString; } return answer; } int main() { std::string str = "abcd"; std::wstring wstr = wstring_from_bytes(str); } 

Regardless, this is much more easily done in newer versions of the standard library (C++ 11 and newer)

#include <locale> #include <codecvt> #include <string> std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter; std::wstring wide = converter.from_bytes(narrow_utf8_source_string); 
Sign up to request clarification or add additional context in comments.

1 Comment

The C++11 portion of the answer worked for me. Thanks!
6

Here is an implementation using wcstombs (Updated):

#include <iostream> #include <cstdlib> #include <string> std::string wstring_from_bytes(std::wstring const& wstr) { std::size_t size = sizeof(wstr.c_str()); char *str = new char[size]; std::string temp; std::wcstombs(str, wstr.c_str(), size); temp = str; delete[] str; return temp; } int main() { std::wstring wstr = L"abcd"; std::string str = wstring_from_bytes(wstr); } 

Here is a demo.

2 Comments

This is funny! First sizeof() does not give you the length of the string, you have strlen or wcslen for that. Second, you didn't check for empty(). Third, you converted the other way around. And last but not least, you leaked the str pointer in your linked example. 😂
I was new to this stuff back then :)
4

printf-style format specifiers are not part of the C++ library and cannot be used to construct a string.

If the string may only contain single-byte characters, then the range constructor is sufficient.

std::string narrower( "hello" ); std::wstring wider( narrower.begin(), narrower.end() ); 

The problem is that we usually use wstring when wide characters are applicable (hence the w), which are represented in std::string by multibyte sequences. Doing this will cause each byte of a multibyte sequence to translate to an sequence of incorrect wide characters.

Moreover, to convert a multibyte sequence requires knowing its encoding. This information is not encapsulated by std::string nor std::wstring. C++11 allows you to specify an encoding and translate using std::wstring_convert, but I'm not sure how widely supported it is of yet. See 0x....'s excellent answer.

Comments

1

The converter mentioned for C++11 and above has deprecated this specific conversion in C++17, and suggests using the MultiByteToWideChar function.

The compiler error (c4996) mentions defining _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING.

1 Comment

How does this answer the question? I think this would be better as a comment under the relevant answer.
0
wstring temp = L""; for (auto c : DATA_DIR) temp.push_back(c); 

Comments

-1

I found this function. Could not find any predefined method to do this.

std::wstring s2ws(const std::string& s) { int len; int slength = (int)s.length() + 1; len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0); wchar_t* buf = new wchar_t[len]; MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len); std::wstring r(buf); delete[] buf; return r; } std::wstring stemp = s2ws(myString); 

8 Comments

This is not using the standard library. It looks like Win32.
Yea, its not using standard library. Asker is using Visual Studio. It can be of help if he is using WINAPI.
And what exactly does CP_ACP do? It appears to specify the a system-defined, non-multibyte encoding. This API makes it very difficult to write portably.
CP_ACP is to define the codepage when MultiByteToWideChar performs the conversion. CP_ACP defines it to be ANSI codepage.
And "ANSI codepage" is an ill-defined concept that is likely not to be what he wants.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.