Red*_*ick 5 windows unicode perl utf-8 codepages
在此输出中,为什么在打印非ASCII Unicode字符后会获得额外的换行符?
平台是Windows Vista,问题发生在chcp 65001
但不是之后chcp 850
C:\>chcp 850 Active code page: 850 C:\>perl unicode_bug_1.pl Budweiser Budweiser Budweiser Bud?øjovick?¢ Budvar Bud?øjovick?¢ Budvar Bud?øjovick?¢ Budvar C:\>chcp 65001 Active code page: 65001 C:\>perl unicode_bug_1.pl Budweiser Budweiser Budweiser Bud?jovický Budvar Bud?jovický Budvar Bud?jovický Budvar
来自这个计划
#!perl
use strict;
use warnings;
binmode (STDOUT, "encoding(UTF-8)"); # so no "Wide character in print" warning
print "Budweiser\n" for 1..3;
print "Bud\N{U+011B}jovick\N{U+00FD} Budvar\n" for 1..3;
Run Code Online (Sandbox Code Playgroud)
这似乎是 Perl 中的一个错误。我原以为这是 Windows 代码页 65001 中的一个错误,控制台并没有真正支持,但我最终用 C 和 Perl 编写了测试程序,并且在 C 版本中没有出现问题。无论 Unicode 字符出现在行中的哪个位置,这种情况都会发生,但您要打印的行必须比控制台支持的宽。
\n\n这是我的 C 程序:
\n\n#include "stdafx.h"\n\n#include "Windows.h"\n\n\nint _tmain(int argc, _TCHAR* argv[])\n{\n BOOL b = SetConsoleOutputCP(65001);\n printf("set console output codepage returned %d\\n", b);\n\n printf("c\xce\xb1fe\\n");\n printf("1234567890 caf\xc3\xa9\\n");\n printf("1234567890 1234567890 c\xce\xb1fe\\n");\n printf("1234567890 1234567890 1234567890 caf\xc3\xa9\\n");\n printf("1234567890 1234567890 1234567890 1234567890 c\xce\xb1fe\\n");\n printf("1234567890 1234567890 1234567890 1234567890 1234567890 caf\xc3\xa9\\n");\n printf("1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 c\xce\xb1fe\\n");\n printf("1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 caf\xc3\xa9\\n");\n printf("1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 c\xce\xb1fe\\n");\n printf("1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 caf\xc3\xa9\\n");\n printf("1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 c\xce\xb1fe\\n");\n printf("1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 caf\xc3\xa9\\n");\n printf("1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 c\xce\xb1fe\\n");\n\n return 0;\n}
Run Code Online (Sandbox Code Playgroud)\n\n这是我的 Perl 程序:
\n\n#\n\nuse utf8;\n\nbinmode STDOUT, \':utf8\';\n\nprintf STDOUT "c\xce\xb1fe\\n";\nprintf STDOUT "1234567890 caf\xc3\xa9\\n";\nprintf STDOUT "1234567890 1234567890 c\xce\xb1fe\\n";\nprintf STDOUT "1234567890 1234567890 1234567890 caf\xc3\xa9\\n";\nprintf STDOUT "1234567890 1234567890 1234567890 1234567890 c\xce\xb1fe\\n";\nprintf STDOUT "1234567890 1234567890 1234567890 1234567890 1234567890 caf\xc3\xa9\\n";\nprintf STDOUT "1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 c\xce\xb1fe\\n";\nprintf STDOUT "1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 caf\xc3\xa9\\n";\nprintf STDOUT "1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 c\xce\xb1fe\\n";\nprintf STDOUT "1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 caf\xc3\xa9\\n";\nprintf STDOUT "1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 c\xce\xb1fe\\n";\nprintf STDOUT "1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 caf\xc3\xa9\\n";\nprintf STDOUT "1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 c\xce\xb1fe\\n";
Run Code Online (Sandbox Code Playgroud)\n\n更新
\n\n不,我错了,在 irc.perl.org 上 #perl 的一些人的帮助下,事实证明这是 Microsoft API 中的一个错误。WriteFile
记录为返回写入的字节数,但返回写入的字符数,这取决于代码页。2010 年 3 月提交了一个错误。
MSDN 论坛中有更多讨论。
\n\n更新2
\n\n我在 Michael Kaplan 的博客“Sorting it all out”中讨论了这个问题,他以题为“隐藏在普通站点中:一封被盗的信件,类似于错误报告”的文章进行了回应。他是微软国际化专家,所以你一定会在那里找到一些见解......
\n