Jeśli dodasz wartość wchar_t
, char16_t
lub char32_t
do wąskiego ostream, wydrukuje ona wartość liczbową punktu kodowego.iostreams - Drukuj wartość `wchar_t` lub` charXX_t` jako znak
#include <iostream>
using std::cout;
int main()
{
cout << 'x' << L'x' << u'x' << U'x' << '\n';
}
wydruki x120120120
. Wynika to z faktu, że istnieje operator<<
dla określonej kombinacji basic_ostream
z jego charT
, ale nie ma analogicznych operatorów dla innych typów znaków, więc są one przekształcane w trybie cichym na int
i drukowane w ten sposób. Podobnie, dla wąskiego literałami łańcuch (L"x"
, u"x"
, U"X"
) są przekształcone do void*
cicho i drukowane wartością wskaźnika, a nie wąski Ciąg przedmiotów (wstring
, u16string
, u32string
) nie będzie jeszcze kompilacji.
Więc pytanie: Jaki jest najmniej okropny sposób, aby wydrukować wchar_t
, char16_t
lub wartości char32_t
na wąskiej ostream, jako znak, a nie jako wartości numerycznej na kod? Powinno poprawnie konwertować wszystkie punkty kodowe, które są reprezentowalne w kodowaniu ostream, do tego kodowania i powinno zgłaszać błąd, gdy nie można przedstawić punktu kodowego. (Na przykład, biorąc pod uwagę u'…'
i UTF-8 ostream sekwencję trzech bajtów 0xE2 0x80 0xA6 powinny być zapisywane w strumieniu, lecz podane u'â'
i ostream KOI8-R błędu należy podać).
Podobnie , jak można wydrukować nie wąski ciąg znaków C lub obiekt typu string na wąskim ostream, konwertując na kodowanie wyjściowe?
Jeśli nie można tego zrobić w ramach ISO C++ 11, przyjmuję odpowiedzi specyficzne dla platformy.
(Zainspirowany this question.)
W skrócie, musisz albo 1) użyć szerokiego ostream, albo 2) przekonwertować dane szerokiego znaku do wąskiego kodowania samodzielnie (co jest potencjalnie stratną konwersją). Ostream nie może zrobić dla ciebie tego nawrócenia. Spójrz na ['std :: wstring_convert'] (http: //en.cppreference.com/w/cpp/locale/wstring_convert) lub użyj biblioteki takiej jak [ICONV] (https://www.gnu.org/software/libiconv/) lub [ICU] (http: // site.icu- project. org /). –