printf 和 std::ostream 在 Windows 控制台下使用 UTF-8 输出有什么区别
What is the different between printf & std::ostream under windows console using UTF-8 output
我有一个将 UTF-8 字符串打印到控制台的程序:
#include <stdio.h>
int main()
{
printf("Мир Peace Ειρήνηn");
return 0;
}
我将控制台配置为使用True Type字体(Lucida控制台(,定义UTF-8代码页(chcp 65001(使用MinGW GCC和Visual Studio 2010编译此程序,它运行良好,我看到:输出:
Мир Peace Ειρήνη
我使用std::cout
做同样的事情
#include <iostream>
int main()
{
std::cout << "Мир Peace Ειρήνηn" ;
return 0;
}
这完全可以正常工作,如上所述使用MinGW GCC,但使用Visual Studio 2010我得到正方形,比正方形更多(每个非ASCII字母两个(。
如果我使用重定向运行程序test >test.txt
我会得到完美的 UTF-8 输出在文件中。
这两项测试都是在Windows 7上完成的。
问题:
- Visual Studio 标准库中的 printf 和 std::cout 在处理输出流方面有什么区别 - 显然其中一个有效而另一个无效?
- 如何解决这个问题?
真实答案:
简而言之:你搞砸了 - std::cout
并不能真正使用 MSVC + UTF-8 - 或者至少需要付出巨大的努力才能使其表现合理。
长篇:阅读答案中引用的两篇文章。
你有一些有缺陷的假设,请先纠正这些假设:
-
似乎可以使用 g++ 并不意味着 g++ 可以正常工作。
-
Visual Studio不是一个编译器,它是一个支持多种语言和编译器的IDE。
-
Visual C++ 的标准库需要修复的结论是正确的,但导致该结论的推理是错误的。此外,g++标准库也需要修复。更不用说 g++ 编译器本身了。
现在,Visual C++将Windows ANSI(由GetACP
API函数指定的编码(作为其未记录的C++执行字符集。即使您的源代码是带有 BOM 的 UTF-8,窄字符串最终也会转换为 Windows ANSI。如果在编译时在您的计算机上是一个包含所有非 ASCII 字符的代码页,那么确定,否则窄字符串将出现乱码。因此,如果不提及源代码编码和 Windows ANSI 代码页,测试结果的描述就严重不完整。
但无论如何,"如果我使用重定向运行程序test >test.txt
我在文件中得到完美的 UTF-8 输出"表明您遇到的是来自 Visual C++ 运行时的一些C++级帮助,它绕过流输出并使用直接控制台输出以获得控制台窗口中显示的正确字符。
当其假设(如 Windows ANSI 编码的窄字符串文本(不成立时,这有助于产生垃圾。
这也意味着当您重定向流时,效果会神秘地消失。然后,运行时库检测到流转到文件,并关闭直接控制台输出功能。您不能保证获得原始原始字节值,但显然您做到了,这是运气不好,因为它掩盖了问题。
顺便说一下,Windows 控制台中的代码页 65001 在实践中不可用。许多程序只是崩溃。包括例如 more
.
获取正确输出的一种方法是直接使用 Windows API 级别,直接使用控制台输出。
使用 C++ 流获取正确的输出要复杂得多。
它是如此复杂,以至于这里没有空间来描述它(正确!(,所以我不得不向你推荐我的两部分博客文章系列:第 1 部分和第 2 部分。
- 递归函数计算序列中的平方和(并输出过程)
- HEX值到wchar_t字符(UTF-8)的转换
- 如何使用 < 和 > 命令获取 c++ 中的输入和输出?
- 请解释"函数1(p1,p2,p3);"的输出
- C++:将控制台输出存储在宏中更好吗
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- 为什么我的代码在输出中增加了93天
- 如何从void函数输出字符串
- 输入到文件并输出到另一个文件,并将流文件传递给函数
- UTF-8字符串上的位XOR操作可提供非UTF-8输出
- setw() 在包含 UTF-8 多字节字符/码位的字符串上输入错误的输出
- printf 和 std::ostream 在 Windows 控制台下使用 UTF-8 输出有什么区别
- C++将UTF-8字符串作为UTF-16输出到std::cout
- XercesC将输出设置为UTF-8
- Linux控制台的国际UTF-32字符串输出
- qDebug输出QString UTF-8非ascii符号,如uxxxx
- 从CreateProcess()中获取UTF-8输出
- Windows CMD不能正确输出UTF-16
- 为什么我在尝试输出UTF-8字符时会得到三个不同的数字