Как я могу печатать символы других языков в Microsoft C++?

Мы можем напечатать любой английский символ с логом, поставив "%c". Возьмем другой случай. Раскладка клавиатуры была изменена. Теперь мой ввод - это корейский/китайский язык. Мы не можем просто поместить «%c» в журнал, чтобы напечатать эти символы.

Как мы можем этого добиться?


person user2702818    schedule 22.12.2015    source источник
comment
Вы хотите сохранить коды клавиш клавиатуры из списка кодов виртуальных ключей (msdn.microsoft.com/en-us/library/windows/desktop/)?   -  person VolAnd    schedule 22.12.2015
comment
Вы используете printf? Почему бы не использовать безопасные по типу потоки ввода-вывода, поскольку это C++?   -  person James Adkison    schedule 22.12.2015
comment
Любой английский символ? Это довольно наивно, взять, например, шип (Þ, þ)...   -  person Ulrich Eckhardt    schedule 22.12.2015


Ответы (2)


Как вы пишете в журнал? Если это printf, я предлагаю переключиться на wprintf и убедиться, что ваш ввод с клавиатуры считывается в wchar_t. Затем вы можете использовать %lc, чтобы распечатать своего персонажа.

Единственная небольшая загвоздка в том, что некоторые китайские иероглифы даже не помещаются в один wchar_t (те, которые содержат символы Unicode U+10000 и выше). Для них вам придется читать массив wchar_t (или std::wstring) и печатать с помощью %ls.

Примечание. Стандарт на самом деле не указывает, насколько большим является wchar_t, а на платформах Unix wchar_t обычно является 32-битным, поэтому он может содержать любую одиночную кодовую точку Unicode как одно значение UTC-4. Windows-NT была разработана до того, как стало очевидно, что 65536 символов недостаточно, поэтому API использовал символы UTC-2. Когда Unicode был расширен до миллиона символов, было бы слишком сложно изменить размер символов, принимаемых API, поэтому они были преобразованы для приема UTF-16. Для взаимодействия с этими API-интерфейсами wchar_t на платформах Windows обычно является значением UTF-16.

Конечно, даже если wchar_t достаточно велико для кодовой точки, это не помогает, когда «символ» занимает более одной кодовой точки. Например, U+005A ЛАТИНСКАЯ ЗАГЛАВНАЯ БУКВА Z и U+0303 ОБЪЕДИНЕНИЕ ТИЛЬДЫ == Z̃ (я не знаю, есть ли язык, который использует это как символ, но, похоже, для него не существует комбинированной формы.)

person Martin Bonner supports Monica    schedule 22.12.2015
comment
Можете ли вы просто использовать wstring для всех из них? И охватывает ли первый метод, который вы описываете, наиболее распространенные китайские иероглифы? - person Flare Cat; 22.12.2015
comment
Да, вы можете использовать wstring для всех из них. Кажется, около 2000 символов; Я не знаю, являются ли они наиболее распространенными. - person Martin Bonner supports Monica; 22.12.2015

Насколько я понимаю, ваша проблема связана с использованием стандартных библиотек ввода-вывода C/C++, поэтому основная проблема заключается в системе ввода-вывода - функции из stdio.h и потоки из iostream предоставляют ввод, зависящий от локализации.

Если вы хотите запомнить (записать в журнал) нажатую клавишу, не принимая во внимание выбранный язык, я предлагаю использовать какой-либо Windows API. Во-первых, прочитайте о вводе с клавиатуры в MSDN и см. виртуальный ключ Коды. Затем обратитесь к примерам обработки сообщения WM_KEYDOWN, например. на справочном форуме по C++.

ИЗМЕНИТЬ:

Но если проблема заключается только в записи корейского языка в файл, решение может быть в локализации и формате данных - рассмотрим следующий пример:

#include <stdio.h>
#include <locale.h>
#include <wchar.h>
int main(void)
{
    // localization (perhaps needed for some computers)
    setlocale(LC_CTYPE, "Korean");
    // open log file for writing 
    FILE* outfile;
    outfile = _wfopen( L"log.txt",L"wt+,ccs=UTF-16LE");
    // test data
    wchar_t wch = L'술';
    // write one character to log file
    fwrite(&wch, sizeof(wchar_t), 1, outfile);
    // close file
    fclose(outfile);

    return 0;
}
person VolAnd    schedule 22.12.2015