Без вывода широких символов в командную строку
Я пытаюсь записать следующий символ в командной строке Windows: ュ (U+FF6D).
Я могу видеть, как персонаж выписывается с помощью WriteConsoleW. Я также могу видеть символ, если я использую WideCharToMultiByte, используя кодовую страницу CP_ACP (chcp возвращает 932: японский). Однако, когда я пытаюсь использовать обычный wcout для той же строки, которую успешно печатает WriteConsoleW, он задыхается.
Когда я выполняю setlocale(LC_ALL, ""), он печатает English_UnitedStates.1252 (кодовая страница по умолчанию, которая была у меня при установке).
Почему безуспешно, когда другие преуспевают?
Примечание: я перезагрузил компьютер, чтобы изменить его системный язык на Японский
2 ответа
Стандартным языком для Cost iostreams всегда является "C" языковой стандарт. Из стандарта C++03, §27.4.2.3/4:
locale getloc() const;
Если не было введено ни одной локали, копия глобальной локали C++,
locale()
, в действительности на момент строительства.
Из §22.1.1.2/1-2:
locale() throw();
Конструктор по умолчанию: снимок текущей глобальной локали.
Создает копию последнего аргумента, переданного
locale::global(locale&)
если это было вызвано; иначе результирующие фасеты имеют семантику виртуальных функций, идентичнуюlocale::classic()
,
Из §22.1.1.5/4-6:
static const locale& classic();
"C" локаль.
Возвращает: локаль, которая реализует классическую семантику локали "C", эквивалентную значению
locale("C")
,Примечания. Этот языковой стандарт, его фасеты и функции-члены не изменяются со временем.
Как std::cout
а также std::wcout
имеют статическую продолжительность хранения, они гарантированно инициализируются до main
вызывается и, следовательно, всегда будет иметь локаль "C" при запуске приложения; то есть нет смысла достаточно рано в исполнении, что можно вызвать locale::global
и измените локаль по умолчанию для std::cout
а также std::wcout
, Таким образом, вы всегда должны наполнять глобальные потоки самостоятельно, если хотите использовать кодовую страницу не по умолчанию.
wcout
создается перед любым кодом в main
выполняет. К тому времени, когда вы звоните setlocale
, wcout
уже там, готов сделать свое дело. Он не пытается отслеживать последующие изменения, которые вы можете сделать с setlocale
, так что он продолжает использовать значение по умолчанию вместо того, что вы установили с setlocale
,