hip*_*ail 19 python windows unicode console perl
Windows控制台至少可以识别十年,并且可能早在Windows NT上.但是由于某些原因,主要的跨平台脚本语言(包括Perl和Python)只输出各种8位编码,因此需要很多麻烦才能解决.Perl给出了"打印中的宽字符"警告,Python给出了一个charmap错误并退出.为什么在这么多年之后它们不仅仅是简单地调用输出UTF-16 Unicode的Win32 -W API而不是通过ANSI /代码页瓶颈强制一切?
仅仅是跨平台性能是低优先级吗?这些语言是否在内部使用UTF-8并且发现输出UTF-16太麻烦了?或者-WAP本身是否破坏到不能按原样使用的程度?
UPDATE
似乎责任可能需要各方共同承担责任.我想象脚本语言只能wprintf在Windows上调用,让操作系统/运行时担心重定向等问题.但事实证明,即使是Windows上的wprintf,也会在打印到控制台之前将宽字符转换为ANSI并返回!
如果这个问题已得到解决,请告诉我,因为错误报告链接似乎已损坏但我的Visual C测试代码仍然无法用于wprintf并成功用于WriteConsoleW.
更新2
实际上,您可以使用C语言将UTF-16打印到控制台,wprintf但前提是这样做_setmode(_fileno(stdout), _O_U16TEXT).
从C你可以将UTF-8打印到一个控制台,其代码页设置为代码页65001,但Perl,Python,PHP和Ruby都有防止这种情况的错误.Perl和PHP通过在包含至少一个宽字符的行之后添加额外的空行来破坏输出.Ruby的损坏输出略有不同.Python崩溃了.
更新3
Node.js是第一个没有出现此问题的脚本语言.
Python开发团队慢慢意识到这是一个真正的问题,因为它是在2007年底首次报道的,并且已经看到了大量的活动,以完全理解并完全修复2016年的错误.
Phi*_*ipp 20
主要问题似乎是在Windows上仅使用标准C库并且不依赖于平台或第三方扩展来使用Unicode是不可能的.您提到的语言源自Unix平台,其实现Unicode的方法与C很好地融合(它们使用普通char*字符串,C语言环境函数和UTF-8).如果你想在C中做Unicode,你或多或少要写两次:一次使用非标准的Microsoft扩展,一次使用标准的C API函数用于所有其他操作系统.虽然这可以做到,但它通常没有高优先级,因为它很麻烦,而且大多数脚本语言开发人员无论如何都讨厌或忽略Windows.
在更技术层面,我认为大多数标准库设计者所做的基本假设是所有I/O流本质上都是基于操作系统级别的字节,对于所有操作系统上的文件和Unix上的所有流都是如此.类似系统,Windows控制台是唯一的例外.因此,如果想要合并Windows控制台I/O,则必须在很大程度上修改许多类库和编程语言标准的体系结构.
另一个更主观的观点是,微软并不足以推广使用Unicode.第一个拥有体面(当时)Unicode支持的Windows操作系统是1993年发布的Windows NT 3.1,早在Linux和OS X增加Unicode支持之前.尽管如此,在这些操作系统中向Unicode的过渡更加无缝且没有问题.微软再次听取了销售人员而不是工程师的意见,并将技术上过时的Windows 9x保留到2001年; 而不是强迫开发人员使用干净的Unicode接口,他们仍然发布破碎的,现在不必要的8位API接口,并邀请程序员使用它(查看Stack Overflow上的一些最新的Windows API问题,大多数新手仍然使用可怕的遗留API!).
当Unicode问世时,许多人意识到它很有用.Unicode最初只是一个纯16位编码,所以很自然地使用16位代码单元.微软然后显然说"好吧,我们有这个16位编码,所以我们必须创建一个16位的API",没有意识到没有人会使用它.然而,Unix名人认为"我们如何以高效和向后兼容的方式将其集成到当前系统中,以便人们真正使用它?" 随后发明了UTF-8,这是一个杰出的工程.就像Unix创建时一样,Unix人们想的更多,需要更长时间,在经济上取得更少的成功,但最终做得恰到好处.
我无法对Perl发表评论(但我认为Perl社区中的Windows仇恨比Python社区更多),但对于Python,我知道BDFL(不喜欢Windows的人)也表示有足够的Unicode支持在所有平台上都是一个主要目标.
对讨论的贡献很小 - 我正在运行捷克本地化的Windows XP,几乎每个地方都使用CP1250代码页.控制台的有趣之处在于它仍然使用传统的DOS 852代码页.
我能够制作非常简单的perl脚本,使用以下命令将utf8编码数据打印到控制台:
binmode STDOUT, ":utf8:encoding(cp852)";
Run Code Online (Sandbox Code Playgroud)
尝试了各种选项(包括utf16le),但只有上面的设置正确打印带有重音的捷克字符.
编辑:我玩了一点问题,发现Win32 :: Unicode.模块导出函数printW在输出和重定向中都能正常工作:
use utf8;
use Win32::Unicode;
binmode STDOUT, ":utf8";
printW "P?íliš žlu?ou?ký k?? úp?l ?ábelské ódy";
Run Code Online (Sandbox Code Playgroud)
我必须解决你的许多问题.
你知道吗
chcp 65001命令来切换终端吗?迈克尔卡普兰有一系列关于cmd控制台和Unicode 的博客文章,可能提供信息(虽然没有真正回答你的问题):
PS:感谢@Jeff查找archive.org链接.
| 归档时间: |
|
| 查看次数: |
2740 次 |
| 最近记录: |