2011-03-14 34 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指令之前,下一行左右的內容正在被舊編碼解釋。

最好的辦法是以二進制模式讀取文件,並使用編碼模塊解碼當前編碼的每一行。