2009-12-05 2 views
4

내 질문을 ActiveState 포럼에 게시하기 전에 여기에서 행운을 시험해보고 싶습니다. :)Perl 스크립트를 Perl 스크립트를 사용하여 실행 파일로 변환 할 때 일부 문자가 누락되는 이유는 무엇입니까?

Perlapp (버전 8.1)을 사용하여 간단한 스크립트를 .exe 파일로 변환하려고합니다. Perl 스크립트는 잘 작동하며 Perlapp도 성공적으로 작업을 수행 한 것으로 보입니다. 하지만 변환 된 .exe 파일에는 utf-8 인코딩과 관련된 이상한 동작이 있습니다. 이미 Perlapp를 구성한

h  hu  zh  s  s  q  gu 

그 utf8.pm 명시 적으로 그래서 : 만이 실행 파일을 실행하는 나에게 줄 것

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

그러나 예를 들어, Perl 스크립트 같은 결과를 얻을 것이다 덧붙여 문제는 사라지지 않을 뿐이다. 나는 다른 것을 시도했다. 예를 들어,

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 (중국어 버전)에서 실행 중이며 스크립트는 BOM이없는 utf-8 인코딩으로 저장됩니다. PerlApp은 BOM이있는 스크립트를 처리 할 수 ​​없습니다. 나는 가능한 조각을 줄 것 인 경우에

편집

, 그럼 나는 그것이 내가 링구아에서 일부 수정을 가지고 세 간 연결의 서브 루틴을 사용하고 있기 때문에 전체 코드를 제공 같아요 가정 :: 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ǔ 
+0

전체 코드를 게시 할 필요는 없지만 작동중인 스 니펫이 필요합니다. $ code와 $ value는 어디서 오는가? –

+0

@Leon, 코멘트 주셔서 감사합니다. 코드 업데이트 됨 : – Mike

+0

'use strict;'를 추가하십시오. 문제를 찾는 데 도움이 될 수 있습니다. –

답변

1

ActiveState가 아직 도움을주지 못했습니다. 도대체 무엇이. 지금은 내 문제에 대한 해결 방법을 알아 냈습니다.이 해결 방법은 매우 이상하게 보입니다.

먼저 나는 다음과 같이 내 데이터 섹션에 어떤 그렇지 않으면 쓸모가 UTF8 인코딩 된 문자를 추가 :

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

그리고 내가 사용 UTF8을 제거; 내 대본에서 pragma; 다음 나는 다음 코드 줄에서 UTF8 플래그를 제거 :

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

가 지금은

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

하게하지만 변경 다음 코드 줄 수 있도록했다 :

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

그런 다음 "와이드 문자 인쇄"경고를 받는다는 것을 제외하고는 모든 것이 괜찮 았습니다.하지만 코드의 또 다른 라인을 추가 :

no warnings; 

을 그리고 난 내 스크립트를 Perlapped 모든 것이 잘 작동 :)

이 정말 이상하다. 나는이 문제가 어떻게 든 OS에 특정한 것으로 의심하고있다. 또한 Windows 시스템에 문제가있을 가능성이 큽니다. 그리고 Perl2exe를 시도했는데 컴파일 된 실행 파일에서 "메모리 0010c4를 읽을 수 없습니다"오류가 발생했습니다. 도대체 무엇이. 내 문제가 어떻게 든 해결됩니다.

관련 문제