我已经阅读了一些文章和论坛帖子讨论这个问题所有解决方案对于这么简单的任务来说似乎太复杂了。
以下是来自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对应文件也不起作用。
在没有进行各种魔术编码转换的情况下,是不是有某种“正确”的方法来完成这项工作?
答案 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_s和fgetws的扩展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
完美地运行。
警告:
不知道这些事情是否会产生太大的差异......
不能代表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;