【问题标题】:Windows UTF-8 printed with chcp 65001 - characters are mysteriously duplicated使用 chcp 65001 打印的 Windows UTF-8 - 字符神秘地重复
【发布时间】:2014-10-24 11:12:53
【问题描述】:

这是我无法理解的一件事:

我使用的是 Windows 7 和 Strawberry Perl 5.20,我想使用 chcp 65001 将 UTF-8 写入控制台 (cmd.exe)。

UTF-8 字符本身输出良好,甚至 >255,但某些字符神秘重复(仅当我不重定向到文件时才会发生这种情况)

编辑: 我现在在last-octet-repeated-when-my-perl-program-outputs-a-utf-8 看到了另一个基本上有相同问题的帖子——解决方案是将 binmode(STDOUT, 'unix:encoding(utf8):crlf') 注入 perl 程序——我已经测试过了现在工作正常

感谢所有研究这个奇怪问题的人。

简而言之,当我重定向到平面文件时,我正在编写一个 UTF-8 字符串 (chr(300) x 3).chr(301)."UVW\x{0D}\x{0A}"然后打印平面文件,一切都很好。

但是,当我直接打印到控制台时,有些字符神秘地重复(我说的是单独一行中的字符“VW”),我不知道为什么

这是我的测试输出

Page de codes active : 65001

Redirected into a file:
-----------------------
ĬĬĬĭUVW

Printed directly:
-----------------
ĬĬĬĭUVW
VW

IO-Layers = (unix crlf)

C4ACC4ACC4ACC4AD5556570D0A

这是我的测试程序:

@echo off
chcp 65001
echo.

set H1=BEGIN{binmode(*STDIN); undef $/;
set HEXDUMP="%H1% print uc(unpack('H*',<STDIN>)), qq{\n}}"

set L1=my @l = PerlIO::get_layers(*STDOUT, output, 1);
set LAYERS="%L1% print {*STDERR} qq{IO-Layers = (@l)\n};"

set PROG="print chr(300) x 3, chr(301), qq{UVW\n};";

set TFILE=%TEMP%\tfile.txt

echo Redirected into a file:
echo -----------------------
perl -C6 -e%PROG% >%TFILE% && type %TFILE%
echo.

echo Printed directly:
echo -----------------
perl -C6 -e%PROG%

echo.
perl -e%LAYERS%
echo.

perl -e%HEXDUMP% <%TFILE%

echo.
pause

正如我所说,字符本身打印正确,但为什么会出现这种神秘的重复? ...以及为什么 * 只有 * 如果没有重定向到文件中?

【问题讨论】:

  • 为什么要打印 U+0300 和 U+0301,分别是“组合重音”和“组合重音”?这些重音符号旨在应用于前面的字符。另外,Windows 系统上的 Perl 会将"\n" 隐式转换为 CRLF,无需自己打印 U+000D。
  • 啊,我明白了。您的实际代码发送 decimal 300 和 301,即 U+012C 和 U+012D,它们分别是“capital I breve”和“small I breve”,与您所说的输出相匹配。即便如此,你为什么要打印这么奇怪的东西?
  • 我正在打印奇怪的东西来测试我的程序就输出而言是坚如磐石的。
  • 我已编辑文本以反映我的代码发送十进制 300 和 301
  • 我在last-octed-repeated-in-utf8 看到了另一个基本上有相同问题的帖子——解决方案是将 binmode(STDOUT, 'unix:encoding(utf8):crlf') 注入 perl 程序-- 我已经测试过了,现在可以正常使用了

标签: windows perl utf-8


【解决方案1】:

正如我所怀疑的,这已被报告为 Windows 软件中的故障:

这是由 Windows 中的错误引起的。写入设置为代码页 65001 的控制台时,WriteFile() 返回写入的字符数而不是字节数。

我不知道有什么变通方法,但如果 :unix:encoding(utf8):crlf PerlIO 堆栈适合您,那么您似乎已经找到了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-18
    • 1970-01-01
    • 1970-01-01
    • 2012-01-13
    • 1970-01-01
    • 2011-01-08
    • 2014-11-19
    • 1970-01-01
    相关资源
    最近更新 更多