Почему некоторые символы отсутствуют, когда я конвертировал свой Perl-скрипт в исполняемый файл с использованием Perlapp? - PullRequest
4 голосов
/ 05 декабря 2009

Прежде чем опубликовать мой вопрос на форуме ActiveState, я хотел бы попытать счастья здесь:)

Я пытаюсь преобразовать мой простой скрипт в файл .exe, используя Perlapp (версия 8.1). Сценарий Perl работает нормально, и, похоже, Perlapp также успешно справился со своей задачей. Но конвертированный файл .exe имеет странное поведение, которое, я считаю, должно быть связано с кодировкой utf-8. Например, скрипт Perl будет выдавать результат вроде:

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

Но запуск исполняемого файла дал бы мне только это:

h      hu     zh     s      s      q      gu

Я уже настроил Perlapp так, чтобы явно добавлялся utf8.pm, но проблема просто не решалась. Я пробовал что-то еще. Например,

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ǔ

И еще одна вещь, я запускаю ActivePerl 5.10.0.on Windows XP (китайская версия), и сценарий сохраняется в кодировке utf-8 без спецификации. PerlApp не может обработать сценарий, который имеет спецификацию.

Редактировать

Если бы я дал работоспособный фрагмент кода, то я полагаю, что это все равно что дать весь код, потому что я использую три взаимосвязанные подпрограммы, которые я использую с некоторыми изменениями из модуля 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ǔ

1 Ответ

1 голос
/ 09 декабря 2009

ActiveState еще не помог мне. Без разницы. Теперь я нашел обходной путь для моей проблемы, и этот обходной путь выглядит очень странно.

Сначала я добавил некоторые другие бесполезные символы в кодировке utf-8 в раздел DATA, например:

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

А потом я убрал использование utf8; прагма из моего сценария; а затем я удалил флаг utf8 из следующей строки кода:

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

Теперь становится

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

Но мне пришлось оставить следующую строку кода без изменений:

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

Тогда все было в порядке, за исключением того, что я получал предупреждения "напечатанные широкие символы". Но я добавил еще одну строку кода:

no warnings;

А потом я Perlapped мой сценарий, и все работало нормально:)

Это действительно странно. Я подозреваю, что эта проблема как-то зависит от конкретной ОС. Также вполне вероятно, что что-то не так с моей системой Windows. И я также попробовал Perl2exe и скомпилированный исполняемый файл дал мне ошибку «память 0010c4 не может быть прочитана». Без разницы. Моя проблема как-то решена мной самостоятельно:)

...