Без вывода широких символов в командную строку

Я пытаюсь записать следующий символ в командной строке 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,

Другие вопросы по тегам