patterncppMinor
Converting from std::wstring to std::string in Linux
Viewed 0 times
stdwstringlinuxconvertingfromstring
Problem
I was bothered by inability of C++ to mix
Converting between std::wstring and std::string
It didn't help me because it was mostly about MS Windows (I'm on Linux), but thanks to it I've found something similar to the
My goal was just to output wide strings to
It works for me now... Will it work in other setups?
cout and wcout in the same program - so I've found this question:Converting between std::wstring and std::string
It didn't help me because it was mostly about MS Windows (I'm on Linux), but thanks to it I've found something similar to the
WideCharToMultiByte functions in the C++ standard library.My goal was just to output wide strings to
cout intermittently with regular strings. I've written two variants of conversion function, which take wide string as an argument and return a regular string, containing multi-byte characters, ready to be sent to the cout (provided that the locale is appropriate).#include
#include
using std::cout;
using std::endl;
struct T
{
std::string a;
std::wstring b;
};
std::string Convert1(const std::wstring& WS)
// ------ conversion using the wcstombs function
{
const unsigned wlen = WS.length();
char buf[wlen * sizeof(std::wstring::value_type) + 1];
const ssize_t res = std::wcstombs(buf, WS.c_str(), sizeof(buf));
return (res >= 0) ? buf : "?";
}
std::string Convert2(const std::wstring& WS)
// ------ conversion using the wcsrtombs function
{
mbstate_t st = {};
const unsigned wlen = WS.length();
wchar_t wbuf[wlen + 1];
const size_t copied = WS.copy(wbuf, wlen);
wbuf[copied] = L'\0';
const wchar_t* wptr = wbuf;
char buf[wlen * sizeof(std::wstring::value_type) + 1];
const ssize_t res = std::wcsrtombs(buf, &wptr, sizeof(buf), &st);
return (res >= 0) ? buf : "?";
}
int main()
{
T t = {"Hello", L"Привет"};
std::setlocale(LC_ALL, "en_US.utf8");
cout << t.a << endl;
cout << Convert2(t.b) << endl;
}It works for me now... Will it work in other setups?
Solution
-
The test should be
-
`
PS: И тебе привет
ssize_t is essentially unsigned; that is, the comparison res >= 0 is always true.The test should be
res != static_cast(-1)-
`
and headers are missing
-
You don't need to WS.copy(wbuf, wlen).
In fact, you don't need wbuf at all:
const wchar_t * wptr = WS.c_str();
std::wcsrtombs(buf, &wptr, sizeof(buf), &st);
works just fine.
-
I am not sure that calculating buffer length via sizeof(std::wstring::value_type) is a right way. How can you be sure that multibyte sequence will fit? I'd recommend to obtain required size by passing NULL to wcsrtombs`.PS: И тебе привет
Code Snippets
res != static_cast<std::size_t>(-1)const wchar_t * wptr = WS.c_str();
std::wcsrtombs(buf, &wptr, sizeof(buf), &st);Context
StackExchange Code Review Q#54000, answer score: 4
Revisions (0)
No revisions yet.