4

Вопрос в том, как это сделать на Windows. На Linux-е это просто

setlocale(LC_CTYPE, "");
//а потом wprintf ...

На Windows такое не катит. Желательно, чтобы вышло как-то так.

#ifdef __linux__ 
  setlocale(LC_CTYPE, "");
#elif defined _WIN32
  //Windows
#else

Нужно для вывода кириллицы, иероглифов и т. п. Нужен именно wchar_t.

P. S. MinGW gcc -dumpversion 4.8.1

P. P. S. На MS Visual C++ 2010 работает ответ 1 (без stdafx.h)

3 Answers3

3

Традиционно поддержка Unicode в консоли Windows очень слаба, и вероятно для Windows вам стоит задуматься о графическом интерфейсе (в нём как раз обычно всё в порядке). В «свежих» версиях Visual Studio рантайм стал умнее, и с поддержкой Unicode стало лучше.

Тем не менее, вам нужен как минимум шрифт, поддерживающий Unicode (например, Lucida Console).

Например, мой экземпляр Visual Studio 2013 с вот таким исходником:

#include "stdafx.h"

#include <fcntl.h>
#include <io.h>
#include <stdio.h>

int main(void)
{
    _setmode(_fileno(stdout), _O_U16TEXT);
    wprintf(L"%s", L"кошка \x65e5\x672c\x56fd\n");
    return 0;
}

выдал на экран кириллицу, но не иероглифы. При редиректе вывода в файл, однако, всё читается правильно. (Это означает, что проблема в шрифте.) С выводом RTL-текстов (иврит, арабский), однако, всё ещё возможны проблемы.

Информация взята отсюда.

(Ответ относится к toolchain'у Visual Studio.)

VladD
  • 206,799
3

Нужно вызвать _setmode(_fileno(stdout), _O_U16TEXT);

#include <iostream>
#include <io.h>
#include <fcntl.h>

int wmain(int argc, wchar_t* argv[])
{
    _setmode(_fileno(stdout), _O_U16TEXT);

    std::wcout << L"Testing unicode -- English -- Ελληνικά -- Español." << std::endl;
    // или
    wprintf(L"Testing unicode -- English -- Ελληνικά -- Español.\n");

    return 0;
}

Поддержка конкретных символов зависит от шрифта консоли. Lucida Console и Consolas справляются со всем, кроме иероглифов.

Решение взято из ответа на en-SO - Output unicode strings in Windows console app

  • Не идёт. Можно попозже с Вами, пожалуйста, я разбираюсь с первым ответом. Если можете, помогите. – Железо Питон Jul 07 '15 at 12:31
  • @ЖелезоПитон Первый ответ отредактирован и теперь совпадает с этим решением. У вас сам по себе файл исходника как unicode сохранен? Попробуйте студией собрать в конце-концов, вдруг проблема в MinGW. –  Jul 07 '15 at 13:51
  • @PashapPash: Проблема точно в MinGW. Студия устанавливается – Железо Питон Jul 07 '15 at 13:55
3

О мой бог, cygwin мне помог... -- говорил когда-то святой Георгий.

Cygwin выручил и меня!

#ifdef __linux__ 
  setlocale(LC_CTYPE, "");
#elif defined _WIN32
  //Windows
#else

Теперь и этого не надо!

Просто

setlocale(LC_CTYPE, "");

Работает и на Linux, и на Windows (cygwin1.dll).

Версия компилятора g++: 4.9.2.

Версия Windows: XP SP3.

  • Ох, Windows XP! Понятно тогда, в старых версиях многое работает не так, как надо. – VladD Jul 08 '15 at 10:19
  • На Windows 7 предложенные решения не работали! – Железо Питон Jul 08 '15 at 10:24
  • @VladD: На Windows 7 предложенные решения не работали! – Железо Питон Jul 08 '15 at 10:30
  • Даже так? Ну что ж, тем лучше, что нашлось универсальное решение. – VladD Jul 08 '15 at 10:44
  • Если ваше решение помогло — не бойтесь отмечать его галочкой. – VladD Jul 08 '15 at 11:11
  • @VladD: Это можно сделать только завтра – Железо Питон Jul 08 '15 at 11:25
  • А _setmode(_fileno(stdout), _O_U16TEXT); не поможет вместо system("chcp 65001 >log.txt");? – VladD Jul 09 '15 at 08:33
  • Нет. Кстати, понял что system("chcp 65001 >log.txt"); utf-8, а мне надо 16. – Железо Питон Jul 09 '15 at 08:58
  • VladD: Или очень стрёмный UTF-16. – Железо Питон Jul 09 '15 at 09:09
  • VladD: В смысле большинство символов занимает 2 wchar_t. – Железо Питон Jul 09 '15 at 09:10
  • @VladD: У MinGW w64 есть большие странности. Не буду перечислять их. Из-за этих странностей промежуточное решение - cygwin. – Железо Питон Jul 09 '15 at 09:25
  • Только будут проблемы с переносом программки на другой комп (где cygwin не поставлен). И кстати, не помню уж точно где, но я с ним нарывался, некотрые функции работают как-то не так (не как в *nix-ах). Из эмуляторов *nix в винде мне больше всего понравился Interix (к сожалению, закончился на XP SP2) – avp Jul 09 '15 at 10:17
  • @avp: У меня вроде бы работало, если утащить с каталогом программы все нужные dll-ки. – VladD Jul 09 '15 at 10:20
  • @VladD, возможно они что-то улучшили (я к cygwin давно не прикасался) – avp Jul 09 '15 at 10:23