为什么脚本语言不将Unicode输出到Windows控制台?

2024-09-27 17:47:24 发布

您现在位置:Python中文网/ 问答频道 /正文

Windows控制台至少有十年的Unicode意识,甚至可以追溯到windowsnt。然而,由于某些原因,主要的跨平台脚本语言(包括Perl和Python)只输出各种8位编码,这需要大量的麻烦来解决。Perl给出一个“宽字符打印”警告,Python给出charmap错误并退出。究竟为什么这么多年后,他们不只是简单地调用输出UTF-16unicode的Win32-wapi,而不是强迫一切通过ANSI/代码页瓶颈?在

只是跨平台的性能是低优先级的吗?是不是这些语言在内部使用了UTF-8,并且发现输出UTF-16太麻烦了?或者-wapi本身就已经损坏到不能按原样使用的程度了吗?在

更新

看来,责任可能需要各方共同承担。我想象脚本语言可以在Windows上调用wprintf,让操作系统/运行时担心诸如重定向之类的事情。但事实证明even wprintf on Windows converts wide characters to ANSI and back before printing to the console!在

请让我知道这是否已经修复,因为错误报告链接似乎断开,但我的visualc测试代码wprintf仍然失败,writesolew仍然成功。在

更新2

实际上,您可以使用wprintf将UTF-16从C打印到控制台,但前提是首先要这样做。在

从C语言可以将UTF-8打印到一个控制台,控制台的代码页被设置为代码页65001,但是Perl、Python、PHP和Ruby都有阻止这一点的bug。Perl和PHP通过在至少包含一个宽字符的行后面添加额外的空行来破坏输出。Ruby的损坏输出略有不同。Python崩溃。在

更新3

在节点.js是第一种没有这个问题的脚本语言。在

自从2016年Python团队发现了一个巨大的漏洞,开发团队慢慢地意识到了这个问题。在


Tags: to代码windows跨平台团队字符脚本语言perl
3条回答

我正在运行捷克本地化的WindowsXP,几乎所有地方都使用CP1250代码页。控制台的有趣之处在于它仍然使用旧的DOS852代码页。在

我能够制作非常简单的perl脚本,使用以下命令将utf8编码的数据打印到控制台:

binmode STDOUT, ":utf8:encoding(cp852)";

尝试了各种选项(包括utf16le),但只有上面的设置正确地打印了重音的捷克字符。在

编辑:我对这个问题进行了更多的研究,发现了Win32::Unicode。模块导出函数printW,该函数在输出和重定向时都能正常工作:

^{pr2}$

我不得不问你许多问题。在

你知道吗

  • Windows使用UTF-16作为其api,但是仍然默认使用用户空间中的各种“有趣”的遗留编码(例如Windows-1252、Windows-1251),包括文件名,这与Windows的许多本地化不同?在
  • 您需要对输出进行编码,并且为系统选择适当的编码是由locale pragma实现的,并且有一个名为locale的POSIX标准是在这个标准上构建的,而Windows与它不兼容?在
  • Perl already supported一次所谓的“宽”api?在
  • 微软设法将UTF-8应用到他们的字符编码代码页系统中,您可以通过发出适当的chcp 65001命令来切换终端吗?在

主要问题似乎是,在Windows上不可能只使用标准C库而不使用依赖于平台或第三方的扩展来使用Unicode。您提到的语言源于Unix平台,Unix平台实现Unicode的方法与C语言很好地融合在一起(它们使用普通的char*字符串、C语言环境函数和UTF-8)。如果你想在C语言中使用Unicode,你或多或少要写两遍:一次使用非标准的Microsoft扩展,一次使用所有其他操作系统的标准C API函数。虽然这是可以做到的,但它通常没有高优先级,因为它很麻烦,而且大多数脚本语言开发人员要么讨厌要么忽略Windows。在

在技术层面上,我认为大多数标准库设计人员的基本假设是,所有I/O流本质上都是基于操作系统级别的字节,这对于所有操作系统上的文件和类Unix系统上的所有流都是如此,只有Windows控制台是唯一的例外。因此,要想集成Windows控制台I/O,就必须对许多类库和编程语言标准进行很大程度的修改

另一个更主观的观点是,微软在推广Unicode的使用方面还不够。第一个支持Unicode的Windows操作系统是WindowsNT3.1,它在1993年发布,比Linux和OSX对Unicode的支持要早得多。不过,在这些操作系统中,向Unicode的过渡已经变得更加无缝和无问题了。微软再次听取销售人员的意见,而不是工程师的意见,并将技术上过时的Windows9x保留到2001年;他们没有强迫开发人员使用干净的Unicode接口,而是仍然提供损坏的、现在不必要的8位API接口,并邀请程序员使用它(看看最近关于堆栈溢出的一些windowsapi问题,大多数新手仍然使用可怕的旧API!)。在

当Unicode问世时,许多人意识到它很有用。Unicode最初是纯16位编码,所以使用16位代码单元是很自然的。微软随后显然说“好吧,我们有16位编码,所以我们必须创建一个16位API”,并没有意识到没有人会使用它。然而,Unix的杰出人士认为“我们如何才能以一种高效且向后兼容的方式将其集成到当前系统中,以便人们能够真正地使用它?”后来又发明了UTF-8,这是一项杰出的工程。就像创建Unix时一样,Unix的人想得更多,需要的时间更长一些,财务上的成功较少,但最终还是做对了。在

我不能评论Perl(但我认为Perl社区中讨厌Windows的人比Python社区中的要多),但是关于Python,我知道BDFL(他也不喜欢Windows)已经声明在所有平台上提供足够的Unicode支持是一个主要目标。在

相关问题 更多 >

    热门问题