[英]C++: output contents of a Unicode file to console in Windows
我已经阅读了很多讨论该问题的文章和论坛帖子,对于这样一个简单的任务,所有解决方案似乎都太复杂了。
以下是直接来自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对应的功能也没有用。
在没有进行各种魔术编码转换的情况下,是否存在某种“正确”的方法来完成此任务?
Windows控制台支持unicode。 它不支持从左到右和“复杂脚本”。 要使用Visual C ++打印UTF-16文件,请使用以下命令:
_setmode(_fileno(stdout), _O_U16TEXT);
并使用wcout
代替cout
。
不支持“ UTF8”代码页,因此对于UTF-8,您将必须使用MultiBytetoWideChar
可以在此博客中找到有关Unicode的更多控制台支持
在Windows上使用cout输出到控制台的正确方法是首先调用GetConsoleOutputCP ,然后将您拥有的输入转换为控制台代码页。 或者,使用WriteConsoleW ,传递wchar_t*
。
要从文件读取UTF-8或UTF-16字符串,可以使用_wfopen_s和fgetws的扩展mode
字符串。 我认为这些扩展还没有C ++接口。 Michael Kaplan的博客中介绍了最简单的打印到控制台的方法 :
#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兼容。
虽然Windows控制台窗口基于UCS-2,但它们不正确支持UTF-8。
您可以使用适当的API函数,通过暂时将控制台窗口的活动输出代码页设置为UTF-8来使事情正常进行。 请注意,这些功能区分输入代码页和输出代码页。 但是,[cmd.exe]确实不喜欢UTF-8作为活动代码页,因此请不要将其设置为永久代码页。
否则,您可以使用Unicode控制台窗口功能。
干杯,……
#include <stdio.h>
int main (int argc, char *argv[])
{
// do chcp 65001 in the console before running this
printf ("γασσο γεο!\n");
}
如果您在运行程序之前在控制台中执行chcp 65001
, chcp 65001
很好。
注意事项:
不知道这些东西是否有太大的不同...
无法在BMP上代表字符,请对其进行旋转并发表评论。
为了清楚起见,这里有人提到了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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.