13

Why

cout<< "привет";

works well while

wcout<< L"привет";

does not? (in Qt Creator for linux)

Minimus Heximus
  • 2,683
  • 3
  • 25
  • 50

1 Answers1

18

GCC and Clang defaults to treat the source file as UTF-8. Your Linux terminal is most probably configured to UTF-8 as well. So with cout<< "привет" there is a UTF-8 string which is printed in a UTF-8 terminal, all is well.

wcout<< L"привет" depends on a proper Locale configuration in order to convert the wide characters into the terminal's character encoding. The Locale needs to be initialized in order for the conversion to work (the default "classic" aka "C" locale doesn't know how to convert the wide characters). Use std::locale::global (std::locale ("")) for the Locale to match the environment configuration or std::locale::global (std::locale ("en_US.UTF-8")) to use a specific Locale (similar to this C example).

Here's the full source of the working program:

#include <iostream>
#include <locale>
using namespace std;
int main() {
  std::locale::global (std::locale ("en_US.UTF-8"));
  wcout << L"привет\n";
}

With g++ test.cc && ./a.out this prints "привет" (on Debian Jessie).

See also this answer about dangers of using wide characters with standard output.

Community
  • 1
  • 1
ArtemGr
  • 11,684
  • 3
  • 52
  • 85
  • thanks. yet it's surprising that "привет" is not std literal it should be `char[]`. – Minimus Heximus Sep 07 '13 at 20:00
  • 1
    @MinimusHeximus: "привет" is char[] in UTF-8 by default, L"привет", however, is wchar[] in UTF-16, UTF-32 or UCS-2. – ArtemGr Sep 08 '13 at 09:07
  • 1
    Code above compiled in Windows gnu g++, outputs this error: `terminate called after throwing an instance of 'std::runtime_error' what(): locale::facet::_S_create_c_locale name not valid`. – Salvador Mar 17 '14 at 20:06
  • 3
    @Salvador So? The question was about Linux. If your GCC port doesn't have the "en_US.UTF-8" locale then catch the exception and use `std::locale::global (std::locale (""))` or install the locale. – ArtemGr Mar 18 '14 at 12:49