2011-03-14 29 views
1

我使用Perl来加载一些“宏”文件。这些宏可以,但是,可以在不同的编码进行编码,因此对于用户书写他们的宏定义的指令(即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"; 
} 

如果我把更多的评论功能之前,所有的字符是OK:

sub macro5_fn { 
    print "žluťoučký kůň úpěl ďábelské ódy\n"; 
} 

简单地说,正确解码字符的数目取决于从#encoding指令这些字符,是接近不正确解码的那些的距离。

在我看来,这是Perl和PerlIO(不)冲洗缓冲区的问题。或者我做错了什么?

谢谢你的回答。

+0

也许我应该提到所有宏都是用 open打开($ file_handle,'<',$ macro_name)' ,然后通过调用'change_encoding($ fh,“utf8”)设置为默认编码。 ' – Peter 2011-03-14 23:03:46

+1

您是否尝试在字节模式下保持句柄,然后使用'$ chars = Encode :: decode($ encoding,$ bytes)'解码为正确的字符格式?这应该避开任何缓冲问题。 – 2011-03-14 23:16:20

回答

5

问题是<>读取的不仅仅是一行,因此在您看到新的#encoding指令之前,下一行左右的内容正在被旧编码解释。

最好的办法是以二进制模式读取文件,并使用编码模块解码当前编码的每一行。