我使用Perl加载一些'宏'文件。但是,这些宏可以用各种编码进行编码,因此为用户编写宏指定了一个指令(即
#encoding iso-8859-2
在宏的开头)。
每次在宏中遇到此指令时,都会调用函数设置编码,看起来像这样:
sub change_encoding {
my ($file_handle, $encoding) = @_;
$file_handle->flush();
binmode($file_handle); # get rid of IO layers
binmode($file_handle,":encoding($encoding)");
}
问题是当我使用标准
读取宏时while($line = <$file_handle>){
process_macro($line);
}
我收到的消息是“utf8”\ xXY“不映射到Unicode”,但仅当带有变音符号的字符靠近#encoding指令时才会出现。我尝试了几个例子,我能够将一半的字符串与\ xXY代码和其他一半的字符串一起使用正确解码的字符,如下所示:
sub macro5_fn {
print "\xBElu\xBBou\xE8k\xFD k\xF9\xF2 úpěl ďábelské ódy\n";
}
如果我在函数前添加了更多注释,则所有字符都可以:
sub macro5_fn {
print "žluťoučký kůň úpěl ďábelské ódy\n";
}
简单地说,正确解码字符的数量取决于#encoding指令中这些字符的距离,关闭的字符不能正确解码。
在我看来,这是Perl和PerlIO(不)刷新缓冲区的问题。或者我做错了什么?
感谢您的回答。
答案 0 :(得分:5)
问题是<>
读取的不仅仅是一行,所以在您看到新的#encoding
指令之前,在旧编码下解释下一行左右。
您最好的选择可能是以二进制模式读取文件并使用Encode模块解码当前编码中的每一行。