Вывод unicode представляет в виде строки в приложении консоли Windows

Привет я пытался произвести строку unicode к консоли с iostreams и отказавший.

Я нашел это: Используя шрифт юникода в консольном приложении C++ и этом отрывке работы.

SetConsoleOutputCP(CP_UTF8);
wchar_t s[] = L"èéøÞǽлљΣæča";
int bufferSize = WideCharToMultiByte(CP_UTF8, 0, s, -1, NULL, 0, NULL, NULL);
char* m = new char[bufferSize]; 
WideCharToMultiByte(CP_UTF8, 0, s, -1, m, bufferSize, NULL, NULL);
wprintf(L"%S", m);

Однако я не нашел способа произвести unicode правильно с iostreams. Какие-либо предложения?

Это не работает:

SetConsoleOutputCP(CP_UTF8);
utf8_locale = locale(old_locale,new boost::program_options::detail::utf8_codecvt_facet());
wcout.imbue(utf8_locale);
wcout << L"¡Hola!" << endl;

РЕДАКТИРОВАНИЕ я не мог найти никакое другое решение, чем перенести этот отрывок в потоке. Надежда, у кого-то есть лучшие идеи.

//Unicode output for a Windows console 
ostream &operator-(ostream &stream, const wchar_t *s) 
{ 
    int bufSize = WideCharToMultiByte(CP_UTF8, 0, s, -1, NULL, 0, NULL, NULL);
    char *buf = new char[bufSize];
    WideCharToMultiByte(CP_UTF8, 0, s, -1, buf, bufSize, NULL, NULL);
    wprintf(L"%S", buf);
    delete[] buf; 
    return stream; 
} 

ostream &operator-(ostream &stream, const wstring &s) 
{ 
    stream - s.c_str();
    return stream; 
} 

68
задан Community 23 May 2017 в 12:10
поделиться

4 ответа

У wcout должна быть локаль, отличная от CRT. Вот как это можно исправить:

int _tmain(int argc, _TCHAR* argv[])
{
    char* locale = setlocale(LC_ALL, "English"); // Get the CRT's current locale.
    std::locale lollocale(locale);
    setlocale(LC_ALL, locale); // Restore the CRT.
    std::wcout.imbue(lollocale); // Now set the std::wcout to have the locale that we got from the CRT.
    std::wcout << L"¡Hola!";
    std::cin.get();
    return 0;
}

Я только что протестировал его, и здесь строка отображается абсолютно нормально.

3
ответ дан 24 November 2019 в 14:20
поделиться

Я не думаю, что есть простой ответ. глядя на Кодовые страницы консоли и Функция SetConsoleCP , кажется, что вам нужно будет установить соответствующую кодовую страницу для набора символов, который вы собираетесь выводить.

0
ответ дан 24 November 2019 в 14:20
поделиться

Недавно я хотел транслировать юникод из Python в консоль windows, и вот тот минимум, который мне нужно было сделать:

  • Вы должны установить консольный шрифт на тот, который покрывает символы юникода. Выбор невелик: Свойства консоли > Шрифт > Lucida Console
  • Необходимо изменить текущую кодовую страницу консоли: выполните chcp 65001 в консоли или используйте соответствующий метод в коде C++
  • пишите в консоль с помощью WriteConsoleW

Посмотрите интересную статью о java unicode на консоли windows

Кроме того, в Python вы не можете писать в стандартный sys. stdout по умолчанию, вам придется заменить его чем-то с помощью os.write(1, binarystring) или прямого вызова обертки вокруг WriteConsoleW. Похоже, что в C++ вам нужно будет сделать то же самое.

0
ответ дан 24 November 2019 в 14:20
поделиться

Во-первых, извините, у меня, вероятно, нет требуемых шрифтов, поэтому я пока не могу его протестировать.

Что-то здесь выглядит подозрительно

// the following is said to be working
SetConsoleOutputCP(CP_UTF8); // output is in UTF8
wchar_t s[] = L"èéøÞǽлљΣæča";
int bufferSize = WideCharToMultiByte(CP_UTF8, 0, s, -1, NULL, 0, NULL, NULL);
char* m = new char[bufferSize]; 
WideCharToMultiByte(CP_UTF8, 0, s, -1, m, bufferSize, NULL, NULL);
wprintf(L"%S", m); // <-- upper case %S in wprintf() is used for MultiByte/utf-8
                   //     lower case %s in wprintf() is used for WideChar
printf("%s", m); // <-- does this work as well? try it to verify my assumption

, а

// the following is said to have problem
SetConsoleOutputCP(CP_UTF8);
utf8_locale = locale(old_locale,
                     new boost::program_options::detail::utf8_codecvt_facet());
wcout.imbue(utf8_locale);
wcout << L"¡Hola!" << endl; // <-- you are passing wide char.
// have you tried passing the multibyte equivalent by converting to utf8 first?
int bufferSize = WideCharToMultiByte(CP_UTF8, 0, s, -1, NULL, 0, NULL, NULL);
char* m = new char[bufferSize]; 
WideCharToMultiByte(CP_UTF8, 0, s, -1, m, bufferSize, NULL, NULL);
cout << m << endl;

как насчет

// without setting locale to UTF8, you pass WideChars
wcout << L"¡Hola!" << endl;
// set locale to UTF8 and use cout
SetConsoleOutputCP(CP_UTF8);
cout << utf8_encoded_by_converting_using_WideCharToMultiByte << endl;
0
ответ дан 24 November 2019 в 14:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: