【发布时间】:2011-06-23 23:02:43
【问题描述】:
Windows 控制台识别 Unicode 至少有十年了,也许早在 Windows NT 就已经存在了。但是由于某种原因,包括 Perl 和 Python 在内的主要跨平台脚本语言只输出各种 8 位编码,需要很多麻烦才能解决。 Perl 给出“打印中的宽字符”警告,Python 给出charmap 错误并退出。为什么这些年来他们不只是简单地调用输出 UTF-16 Unicode 的 Win32 -W API,而不是强迫一切通过 ANSI/代码页瓶颈?
只是跨平台性能的优先级低吗?是不是这些语言在内部使用 UTF-8 并且觉得输出 UTF-16 太麻烦了?还是 -W API 本身就被破坏到无法按原样使用的程度?
更新
看来,责任可能需要由各方共同承担。我想象脚本语言可以在 Windows 上调用 wprintf 并让操作系统/运行时担心诸如重定向之类的事情。但事实证明even wprintf on Windows converts wide characters to ANSI and back before printing to the console!
请让我知道这是否已修复,因为错误报告链接似乎已损坏,但我的 Visual C 测试代码对于 wprintf 仍然失败并且对于 WriteConsoleW 成功。
更新 2
实际上,您可以使用 wprintf 从 C 将 UTF-16 打印到控制台,但前提是您先使用 _setmode(_fileno(stdout), _O_U16TEXT)。
从 C 语言中,您可以将 UTF-8 打印到代码页设置为代码页 65001 的控制台,但是 Perl、Python、PHP 和 Ruby 都存在阻止这种情况的错误。 Perl 和 PHP 通过在包含至少一个宽字符的行后面添加额外的空行来破坏输出。 Ruby 的损坏输出略有不同。 Python 崩溃。
更新 3
Node.js 是第一个开箱即用且没有此问题的脚本语言。
自it was first reported back at the end of 2007 以来,Python 开发团队慢慢意识到这是一个真正的问题,并在 2016 年看到了大量活动来完全理解和完全修复该错误。
【问题讨论】:
-
你不能“输出 Unicode”。 Unicode 是一种在内部将字符表示为代码点的方法。要输出它,您需要某种形式的编码 - 可能是 UTF-8。
-
当然可以输出Unicode。在 *nix 上,输出 Unicode 的标准编码是 UTF-8。在 Windows 上,标准的输出方式是 UTF-16,除了在 Windows 世界中,当他们表示 UTF-16 时,他们说“Unicode”。这可能也适用于 Java 以及 UTF-8 不是主要的任何其他地方。
-
@Daniel:如果您不喜欢该术语,请将其替换为“如果满足适当的条件(字体支持等),请在控制台上打印任意 Unicode 字符”。 UTF-8 是 Unicode 标准的一部分,它的作用远不止分配代码点。
-
@Daniel:Unicode 有特定的术语,其中“编码”意味着“将字符表示为代码点的方法”。将此与代表“Unicode 转换格式”的 UTF 进行比较,后者是将代码点表示为字节或单词流等的过程。在 Unicode 世界之外,字符到数字(代码点)的映射以及一系列代码点的转换成一串字节或单词被模糊在一起作为“编码”。也许令人困惑和烦人,但就是这样。
-
node.js 是我发现的第一个脚本语言,它可以在 *nix 和 Windows 系统的控制台中使用 Unicode 开箱即用!当然,它的目的不是作为常规脚本语言,而是用于服务器大小的基于节点的东西,因此缺少脚本语言所期望的许多功能。 (It's not easy to read text line-by-line for instance.)
标签: python windows perl unicode console