这似乎是 Perl 中的一个错误。我曾认为这是 Windows 代码页 65001 中的一个错误,控制台并不真正支持,但我最终用 C 和 Perl 制作了测试程序,并且在 C 版本中没有发生该问题。无论 Unicode 字符出现在行中的哪个位置都会发生这种情况,但您要打印的行必须比控制台支持的更宽。
这是我的 C 程序:
#include "stdafx.h"
#include "Windows.h"
int _tmain(int argc, _TCHAR* argv[])
{
BOOL b = SetConsoleOutputCP(65001);
printf("set console output codepage returned %d\n", b);
printf("cαfe\n");
printf("1234567890 café\n");
printf("1234567890 1234567890 cαfe\n");
printf("1234567890 1234567890 1234567890 café\n");
printf("1234567890 1234567890 1234567890 1234567890 cαfe\n");
printf("1234567890 1234567890 1234567890 1234567890 1234567890 café\n");
printf("1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 cαfe\n");
printf("1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 café\n");
printf("1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 cαfe\n");
printf("1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 café\n");
printf("1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 cαfe\n");
printf("1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 café\n");
printf("1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 cαfe\n");
return 0;
}
这是我的 Perl 程序:
#
use utf8;
binmode STDOUT, ':utf8';
printf STDOUT "cαfe\n";
printf STDOUT "1234567890 café\n";
printf STDOUT "1234567890 1234567890 cαfe\n";
printf STDOUT "1234567890 1234567890 1234567890 café\n";
printf STDOUT "1234567890 1234567890 1234567890 1234567890 cαfe\n";
printf STDOUT "1234567890 1234567890 1234567890 1234567890 1234567890 café\n";
printf STDOUT "1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 cαfe\n";
printf STDOUT "1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 café\n";
printf STDOUT "1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 cαfe\n";
printf STDOUT "1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 café\n";
printf STDOUT "1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 cαfe\n";
printf STDOUT "1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 café\n";
printf STDOUT "1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 cαfe\n";
更新
不,我错了,在 irc.perl.org 上#perl 的一些人的帮助下,事实证明这是 Microsoft API 中的一个错误。WriteFile
记录返回写入的字节数,但返回写入的字符数,这取决于代码页。2010 年 3 月提交了一个错误。
MSDN 论坛中有更多讨论。
更新 2
我发布了 Michael Kaplan 的博客“Sorting it all out”,关于这个问题,他回复了一篇题为“隐藏在普通网站中:一个被盗的信件类型的错误报告”的文章。他是 Microsoft 国际化专家,因此您一定会在那里找到一些见解......