为什么Perl的编码层没有任何影响?

问题描述 投票:4回答:2

我需要读取一个用iso-8859-1编码的文件。

出于某种原因,我无法使用编码层(如PerlIO::encoding中所述)。这是我正在做的最小例子。

test.txt包含以iso-8859-1编码的单磅符号。

% iconv -f iso-8859-1 test.txt
£

% hexdump -C test.txt
00000000  a3 0a                                             |..|
00000002

我的Perl脚本:

#!/bin/perl

use warnings;
use strict;

open my $f, "<:encoding(iso-8859-1)", $ARGV[0] or die qq{Could not open $ARGV[0]: $!};

while (<$f>) {
  print;
}

结果:

% ./script.pl test.txt | hexdump -C
00000000  a3 0a                                             |..|
00000002

因此脚本会打印它读取的确切字节序列,而不执行转换。

perl character-encoding
2个回答
4
投票

字符串是(32位或64位)数字的序列。

在包含已解码文本的字符串中,这些数字是Unicode代码点。由于字节A3代表iso-8859-1下的Unicode Code Point U+00A3,因此decode("iso-8859-1", "\xA3")返回"\xA3"

您继续打印该字符串,并且print("\xA3")在没有编码层的文件句柄上生成字节A3(因为它需要一个字节字符串)。


你没有指定你想做什么,但我猜你想让程序将输入从iso-8859-1转换为UTF-8。为此,

use open ':std', ':encoding(locale)';

要么

use open ':std', ':encoding(UTF-8)';

这些将编码层添加到STDIN,STDOUT和STDERR(使用binmode),并在范围内为open设置默认编码层。


4
投票

我假设没有使用特定编码声明的文件句柄默认使用utf-8编码,但显然不是这样。

添加一个明确的

binmode(STDOUT, ":utf8");

解决了这个问题。

© www.soinside.com 2019 - 2024. All rights reserved.