I was bothered by inability of C++ to mix 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 <iostream>
#include <string>
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?