我有一个C++程序,它输出原始的UTF-8,在Linux上可以正常工作,但是在Windows shell上输出就不那么好了。例如,“®”变成了“«",“©”变成了“”。代码中还有一个Python部分,当打印到shell时,它似乎工作得更好,所以我试着测试一下Python输出。
PS C:\Users\user> python -c 'print("\N{GREEK CAPITAL LETTER DELTA}")' > test_file_python.txt
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Users\user\AppData\Local\Programs\Python\Python310\lib\encodings\cp1252.py", line 19, in encode
return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode character '\u0394' in position 0: character maps to <undefined>
PS C:\Users\user> python -X utf8 -c 'print("\N{GREEK CAPITAL LETTER DELTA}")' > test_file_python.txt
PS C:\Users\user> cat test_file_python.txt
Δ
PS C:\Users\user> python -c 'print("\N{GREEK CAPITAL LETTER DELTA}")'
Δ
PS C:\Users\user> cat .\test_file_python_wsl.txt # Generated in WSL with the above commands
Δ
PS C:\Users\user> Format-Hex .\test_file_python.txt
Label: C:\Users\user\test_file_python.txt
Offset Bytes Ascii
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
------ ----------------------------------------------- -----
0000000000000000 E2 95 AC C3 B6 0D 0A �ö��
PS C:\Users\user> Format-Hex .\test_file_python_wsl.txt
Label: C:\Users\user\test_file_python_wsl.txt
Offset Bytes Ascii
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
------ ----------------------------------------------- -----
0000000000000000 CE 94 0A ��
字符串
我不明白PowerShell是如何处理编码的,Python在写shell的时候是如何做到这一点的,而在重定向的时候却不行,为什么在WSL中的Linux Bash中完美工作的东西在新的跨平台PowerShell Core中会出现这种问题,而后者应该“正常工作”。
编辑:我忘了添加一些重要信息,我使用PowerShell Core v7.3.6和此编码设置:
PS C:\Users\user> $OutputEncoding
Preamble :
BodyName : utf-8
EncodingName : Unicode (UTF-8)
HeaderName : utf-8
WebName : utf-8
WindowsCodePage : 1200
IsBrowserDisplay : True
IsBrowserSave : True
IsMailNewsDisplay : True
IsMailNewsSave : True
IsSingleByte : False
EncoderFallback : System.Text.EncoderReplacementFallback
DecoderFallback : System.Text.DecoderReplacementFallback
IsReadOnly : True
CodePage : 65001
型
1条答案
按热度按时间zphenhs41#
在Windows上,这个难题有两个部分:
chcp 65001
,这是你从cmd.exe
所做的,是 * 不是 * 一个选项,因为.NET * 缓存 * 存储在[Console]
中的编码):字符串
-X utf8
(大小写)传递给python
可执行文件:型
$env:PYTHONUTF8=1
通过一次性配置步骤的替代方法是将您的计算机切换为使用UTF-8 * 系统范围*,在这种情况下,上述步骤是不必要的;但是,*这具有 * 深远的影响 ,可能会破坏遗留脚本和应用程序-请参阅this answer。
背景信息:
[Console]::OutputEncoding
中的.NET所反映的那样,这是外部程序在编码其输出时至少在历史上预期使用的。$OutputEncoding
首选项变量中的编码,该变量具有意外的默认值:65001
,至少使交互式PowerShell会话也默认为UTF-8(针对 * 外部程序 *)。