4

私の質問を ActiveState フォーラムに投稿する前に、ここで運試しをしたいと思います :)

Perlapp (バージョン 8.1) を使用して、単純なスクリプトを .exe ファイルに変換しようとしています。Perl スクリプトは正常に動作し、Perlapp も正常に機能したようです。しかし、変換された .exe ファイルには奇妙な動作があり、これは utf-8 エンコーディングに関連していると思われます。たとえば、Perl スクリプトは次のような結果を生成します。

hàn    huáng  zhòng  sè     sī     qīng   guó 

しかし、実行可能ファイルを実行すると、これだけが得られます。

h      hu     zh     s      s      q      gu

utf8.pm が明示的に追加されるように Perlapp を既に構成しましたが、問題は解決しません。私は何か他のものを試しました。例えば、

binmode DATA, ":utf8"; 

">:encoding(utf8)"

しかし運がない。

何が原因であるかについて、誰か親切にヒントを教えてもらえますか?いつもありがとう:)

ここにコード全体を投稿できますが、不要なようですので、問題に関連すると思われるコードのスニペットをいくつか貼り付けます。

use utf8;

%zidian = map {chomp;split/\s+/,$_,2} <DATA>;

open my $in,'<:utf8',"./original.txt";
open my $out,'>:utf8',"./modified.txt";

if ( $code~~%zidian) {
           $value = lc$zidian{$code};
}

__DATA__
3400    Qiū
3401    TIǎN
3404    KUà
3405    Wǔ

もう1つ、Windows XP(中国語版)でActivePerl 5.10.0.を実行しており、スクリプトはBOMなしのutf-8エンコーディングとして保存されています。PerlApp は、BOM を持つスクリプトを処理できません。

編集

実行可能なスニペットを与えるとしたら、コード全体を与えるようなものだと思います。これは、相互に接続された 3 つのサブルーチンを使用しているためです。これには、Lingua::han::Pinyin モジュールと Lingua:: からいくつかの変更を加えています。 han::Utils モジュール。

#! perl
# to make good vertical alignment,
# set font family to SonTi and font size to Four(12pts)
use utf8;


sub Unihan {
    my $hanzi = shift;
    my @unihan = map { uc sprintf("%x",$_) } unpack ("U*", $hanzi);
    }

sub csplit {
    my $hanzi = shift;
    my @return_hanzi;
    my @code = Unihan($hanzi);
    foreach my $code (@code) {
        my $value = pack("U*", hex $code);
        push @return_hanzi, $value if ($value);
    }
    return wantarray ? @return_hanzi : join( '', @return_hanzi );
    }

%zidian = map {chomp;split/\s+/,$_,2} <DATA>;

sub han2pinyin {
    my $hanzi = shift;
    my @pinyin;
    my @code = Unihan($hanzi);
     foreach $code (@code) {
           if ( $code~~%zidian) {
           $value = lc$zidian{$code};
        }
        else {
            $value = " ";
        }
        push @pinyin, $value;
    }
    return wantarray ? @pinyin : join( '', @pinyin );
}

open $in,'<:utf8',"./original.txt";
seek $in, 3,0;
open $out,'>:utf8',"./modified.txt";

while(<$in>){
     s/(.{18})/$1\n/g;
     push @tmp, $_;
}

foreach (@tmp){
my @hanzi;
my @pinyin;
@hanzi = csplit($_);
my $hang = join "", @hanzi;
@pinyin = han2pinyin($hang);

for ( my $i = 0; $i < @hanzi && $i < @pinyin; ++$i ) {
           if ( $hanzi[$i] =~ /[\xEFBC8C]|[\xE38082]|[\xEFBC81]|[\xEFBC9F]|[\xE2809C]|[\xE2809D]|[\xEFBC9A]/ ) {
            splice(@pinyin, $i, 0," ");
        }
       }

printf $out "%-7s" x @pinyin, @pinyin;
print $out "\n";
printf $out "%-6s" x @hanzi, @hanzi;
print $out "\n";
}


__DATA__
    3400    Qiū
    3401    TIǎN
    3404    KUà
    3405    Wǔ
4

1 に答える 1

1

ActiveState はまだ何の助けにもなっていません。なんでもいい。今、私の問題の回避策を見つけましたが、この回避策は非常に奇妙に見えます。

最初に、次のように、UTF-8 でエンコードされた無用な文字を DATA セクションに追加しました。

__DATA__
aardvark 'ɑ:dvɑ:k
aardwolf 'ɑ:dwulf
aasvogel 'ɑ:sfәugәl
3400    Qiū
3401    TIǎN
3404    KUà
3405    Wǔ

そして、use utf8; を削除しました。私のスクリプトからのプラグマ。次に、次のコード行から utf8 フラグを削除しました。

open $out,'>:utf8',"./modified.txt";

今はこうなります

open $out,'>',"./modified.txt";

ただし、次のコード行は変更しないでおく必要がありました。

open $in,'<:utf8',"./original.txt";

その後、「ワイド文字が印刷されています」という警告が表示されることを除いて、すべて問題ありませんでした。しかし、別のコード行を追加しました。

no warnings;

そして、私は自分のスクリプトをPerlappedし、すべてがうまくいきました:)

これは本当に奇妙です。この問題は何らかの形で OS 固有のものであると思われます。また、Windows システムに問題がある可能性も非常に高いです。また、Perl2exe も試してみましたが、コンパイルされた実行可能ファイルで「メモリ 0010c4 を読み取れません」というエラーが表示されました。なんでもいい。私の問題は何とか自分で修正しました:)

于 2009-12-09T11:27:47.167 に答える