C ++:在Windows中将Unicode文件的内容输出到控制台

时间:2011-02-05 19:35:59

标签: c++ windows unicode console

我已经阅读了一些文章和论坛帖子讨论这个问题所有解决方案对于这么简单的任务来说似乎太复杂了。

以下是来自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 个答案:

答案 0 :(得分:6)

Windows控制台支持unicode。它不支持从左到右和“复杂脚本”。要使用Visual C ++打印UTF-16文件,请使用以下命令:

   _setmode(_fileno(stdout), _O_U16TEXT);   

并使用wcout代替cout

不支持“UTF8”代码页,因此对于UTF-8,您必须使用MultiBytetoWideChar

可以在this blog

中找到有关unicode的控制台支持的更多信息

答案 1 :(得分:2)

使用cout在Windows上输出到控制台的正确方法是首先调用GetConsoleOutputCP,然后将您输入的内容转换为控制台代码页。或者,使用WriteConsoleW,传递wchar_t*

答案 2 :(得分:1)

要从文件中读取UTF-8或UTF-16字符串,您可以使用_wfopen_sfgetws的扩展mode字符串。我认为这些扩展还没有C ++接口。在Michael Kaplan's blog

中描述了打印到控制台的最简单方法
#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的兼容性。

答案 3 :(得分:0)

虽然Windows控制台窗口是基于UCS-2的,但它们不能正确支持UTF-8。

您可以通过使用适当的API函数暂时将控制台窗口的活动输出代码页设置为UTF-8来使其工作正常。请注意,这些功能区分输入代码页和输出代码页。但是,[cmd.exe]确实不喜欢UTF-8作为活动代码页,因此不要将其设置为永久代码页。

否则,您可以使用Unicode控制台窗口功能。

干杯&amp;第h。,

答案 4 :(得分:0)

#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
  • 代码在一个没有BOM编码为UTF-8的文件中 - 我在文本编辑器中编写它,而不是使用VC ++ IDE,然后使用VC ++编译它。
  • 控制台有TrueType字体 - 这很重要

不知道这些事情是否会产生太大的差异......

不能代表BMP发言,给它一个旋转并留下评论。

答案 5 :(得分:-1)

为了清楚起见,有些人提到过UTF8。 UTF8是一种多字节格式,在某些文档中被错误地称为Unicode。 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之间切换,并且还删除了ASCII构建的_setmode调用,因此允许编译ASCII和UNICODE。这有效。我还没有使用std :: endl进行测试,但我可能会使用wcout和Unicode(不确定),即。

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