栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

chcp 65001代码页导致程序终止,没有任何错误

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

chcp 65001代码页导致程序终止,没有任何错误

要在Windows控制台中使用Python
2.7和3.x(3.6之前)的Unipre,请安装并启用win_unipre_console。像其他cmd.exe和powershell.exe这样的可识别Unipre的控制台程序一样,它使用宽字符函数

ReadConsoleW
WriteConsoleW
。对于Python 3.6,添加了新的
io._WindowsConsoleIO
原始I /
O类。它读取和写入UTF-8编码的文本(为了与Unix跨平台兼容-“获取字节”-程序),但是在内部它通过与UTF-16LE进行代码转换来使用宽字符API。

对于所有Windows版本(包括Windows 10)(包括Windows
10),在控制台中都可以重现您使用非ASCII输入遇到的问题。控制台主机进程(即conhost.exe)并非为UTF-8(代码页65001)和尚未进行更新以始终如一地支持它。特别是,非ASCII输入导致空读取。反过来,这会导致Python的REPL退出并内置

input
来引发
EOFError

问题是conhost假设单字节代码页(例如西方语言环境中的OEM和ANSI代码页)(例如437、850、1252),对UTF-16输入缓冲区进行编码。UTF-8是一种多字节编码,其中非ASCII字符被编码为2到4个字节。要处理UTF-8,将需要对

M/4
字符进行多次迭代编码,其中M是N字节缓冲区中可用的剩余字节。相反,它假定读取N个字节的请求就是读取N个字符的请求。然后,如果输入包含一个或多个非ASCII字符,则
WideCharToMultiByte
由于缓冲区大小不足,内部调用将失败,并且控制台将返回“成功”的0字节读取。

如果安装了pyreadline模块,则在Python 3.5中可能不会完全观察到此问题。Python
3.5自动尝试导入

readline
。在pyreadline的情况下,输入是通过宽字符函数读取的
ReadConsoleInputW
。这是读取控制台输入记录的低级功能。原则上,它应该起作用,但实际上
print('ä')
,REPL将输入读为
print('')
。对于非ASCII字符,
ReadConsoleInputW
返回一个Alt
+
Numpad
KEY_EVENT
记录序列。该序列是有损的OEM编码,除了最后一条记录(该记录在
UnipreChar
字段中具有输入字符)外,可以忽略。显然pyreadline忽略了整个序列。

在Windows
8之前,使用代码页65001的输出也已损坏。它按与非ASCII字符数成比例的方式打印一堆垃圾文本。在这种情况下的问题是,

WriteFile
WriteConsoleA
错误地返回的写入屏幕缓冲液代替的UTF-8字节数UTF-16码的数目。这使Python的缓冲编写器感到困惑,导致重复写入它认为剩余的未写入字节。在Windows
8中,此问题已得到解决,这是重写内部控制台API以使用ConDrv设备而不是LPC端口的一部分。较早版本的Windows可以使用ConEmu或ANSICON来解决此错误。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/641248.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号