C ++: вывод содержимого Unicode-файла на консоль в Windows - PullRequest
5 голосов
/ 05 февраля 2011

Я прочитал кучу статей и постов на форумах, обсуждающих эту проблему, все решения кажутся слишком сложными для такой простой задачи.

Вот пример кода прямо с cplusplus.com :

// reading a text file
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main () {
  string line;
  ifstream myfile ("example.txt");
  if (myfile.is_open())
  {
    while ( myfile.good() )
    {
      getline (myfile,line);
      cout << line << endl;
    }
    myfile.close();
  }

  else cout << "Unable to open file"; 

  return 0;
}

Работает нормально, если в example.txt есть только символы ASCII.Все становится грязно, если я пытаюсь добавить, скажем, что-то на русском языке.

В GNU / Linux это так же просто, как сохранить файл как UTF-8.

В Windows это не такРабота.Преобразование файла в UCS-2 Little Endian (что, по-видимому, Windows использует по умолчанию) и замена всех функций на их аналоги wchar_t тоже не помогают.

Разве нет какой-то "правильный "способ сделать это, не делая все виды магических преобразований кодировки?

Ответы [ 6 ]

6 голосов
/ 06 февраля 2011

Консоль Windows поддерживает Unicode, вроде.Он не поддерживает слева направо и «сложные сценарии».Чтобы напечатать файл UTF-16 с помощью Visual C ++, используйте следующее:

   _setmode(_fileno(stdout), _O_U16TEXT);   

И используйте wcout вместо cout.

Нет поддержки для "UTF8"кодовая страница, поэтому для UTF-8 вам придется использовать MultiBytetoWideChar

Подробнее о поддержке консоли Unicode можно найти в этом блоге

2 голосов
/ 05 февраля 2011

Правильный способ вывода на консоль в Windows с помощью cout - сначала вызвать GetConsoleOutputCP , а затем преобразовать введенные данные в кодовую страницу консоли. Либо используйте WriteConsoleW , передавая wchar_t*.

1 голос
/ 06 февраля 2011

Для чтения строк UTF-8 или UTF-16 из файла вы можете использовать расширенную строку mode из _wfopen_s и fgetws .Я не думаю, что есть интерфейс C ++ для этих расширений еще.Самый простой способ печати на консоли описан в блоге Майкла Каплана :

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

int main(void) {
    _setmode(_fileno(stdout), _O_U16TEXT);
    wprintf(L"\x043a\x043e\x0448\x043a\x0430 \x65e5\x672c\x56fd\n");
    return 0;
}

Избегайте GetConsoleOutputCP, он сохраняется только для совместимости с 8-битным API.

0 голосов
/ 30 сентября 2013

Просто чтобы прояснить, некоторые здесь упоминали UTF8. UTF8 - это многобайтовый формат, который в некоторых документах ошибочно называют Unicode. Юникод всегда только два байта.

Я использовал это ранее опубликованное решение с Visual Studio 2008. Я не знаю, работает ли с более поздними версиями Visual Studio.

   #include <iostream>
   #include <fnctl.h>
   #include <io.h>
   #include <tchar.h>

   <code ommitted>


   _setmode(_fileno(stdout), _O_U16TEXT); 

   std::wcout << _T("This is some text to print\n");

Я использовал макросы для переключения между std :: wcout и std :: cout, а также для удаления вызова _setmode для сборок ASCII, что позволяет компилировать ASCII и UNICODE. Это работает. Я еще не тестировал с использованием std :: endl, но я мог бы работать с wcout и Unicode (не уверен), т.е.

   std::wcout << _T("This is some text to print") << std::endl;
0 голосов
/ 07 февраля 2011
#include <stdio.h>

int main (int argc, char *argv[])
{
    // do chcp 65001 in the console before running this
    printf ("γασσο γεο!\n");
}

Отлично работает , если вы делаете chcp 65001 в консоли перед запуском вашей программы.

Предостережения:

  • Я использую 64Бит Windows 7 с VC ++ Express 2010
  • Код находится в файле, закодированном как UTF-8 без спецификации - я написал его в текстовом редакторе, не используя IDE VC ++, а затем использовал VC ++ для его компиляции.
  • Консоль имеет шрифт TrueType - это важно

Не знаю, слишком ли важны эти вещи ...

Не могу говорить заснимает BMP, крутит его и оставляет комментарий.

0 голосов
/ 05 февраля 2011

Хотя окна консоли Windows основаны на UCS-2, они не поддерживают должным образом UTF-8.

Вы могли бы заставить все работать, установив кодовую страницу активного вывода окна консоли наUTF-8 временно, используя соответствующие функции API.Обратите внимание, что эти функции различают входную кодовую страницу и выходную кодовую страницу.Однако [cmd.exe] действительно не нравится UTF-8 как активная кодовая страница, поэтому не устанавливайте его как постоянную кодовую страницу.

В противном случае вы можете использовать функции окна консоли Unicode.

Приветствия и hth.,

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...