• ベストアンサー

jcodeを使ったgetcode

Perlで日本語を扱う際にjcode.plを使いたいと思いました。 問題点はgetcodeを使用した際に文字コードが出力されなかったということです。 'あ'はsjisと出るのですが 'a'は出力がありません。 文字コードが判別できなくてもなんらかの出力は得られるとWebで見たのでなぜ このような現象になるのか質問させていただきました。 参考にしたサイト http://www.mikeneko.ne.jp/~lab/kcode/jcode.html [ソース] #!/usr/local/bin/perl require './jcode.pl'; print "Content-type: text/html\n\n"; $line = 'あ'; $code = &jcode::getcode(\$line); print "print1 = $code\n"; $line = 'a'; $code = &jcode::getcode(\$line); print "print2 = $code\n"; [結果(コマンドプロンプト上)] Content-type: text/html print1 = sjis print2 = このようになる原因を知りたいです。回答や実行環境への質問などお願いします。 実行環境 1 OS: WindowsXP SP1a webサーバ: Apache 1.3.27 Perl: ActivePerl 5.8.0 ブラウザ: IE6.0 実行環境 2 infoseek無料webスペース

noname#6323
noname#6323
  • Perl
  • 回答数5
  • ありがとう数3

質問者が選んだベストアンサー

  • ベストアンサー
  • leaz024
  • ベストアンサー率75% (398/526)
回答No.5

> undef != ヌルという認識でよろしいのでしょうか 「ヌル」という言葉は色々な意味に使われるので曖昧なのですが、もし「空文字列」のことを指しているのであれば、この認識は正しいです。 未定義値や空文字列などは、次のように分類されます。   データ    ├──────────┐   定義値           未定義値    ├───────┐  (undef)    真          偽  (その他)  (0, 空文字列, 空リスト) 一度も使用していない、または undef() を実行した変数は未定義値となります。 ちなみに論理演算(条件判定など)においては、未定義値は偽となります。 > なんとなく'未定義'を返すというのが変わっている(?)と感じた undef を返す関数は結構あります。 getcode の場合、別に undef ではなく 0 や '' を返したってよいと思いますが、この辺は作者の好みでしょう。 (「判別不能→未定義」というニュアンスの問題かな?とも思います。) 結果を論理演算に使うことがメインとなる関数では 0 か 1 を返せば済みますが、0 の代わりに undef を返しても問題はありません。 しかし、何らかの計算を行う関数などでは、結果が 0(偽)になることも考えられますから、オーバーフローなどのエラーを undef で表現するというのは十分に考えられます。

noname#6323
質問者

お礼

毎回早い回答ありがとうございました。 図解までしていただき非常にわかりやすかったです。 説明も私のレベルに合わせていただいた感じを受け非常に感謝しています。 結論を勝手にまとめます ・getcode は'euc','jis','sjis','binary',undefを返す。 ・ASCIIはundefになる ・undef は definedで偽となるものである。 ・undefは未定義である。なお0,空文字列,空リストは定義値である まとめて書いて申し訳ありませんがdeagleとleaz024さんありがとうございました。大変助かりました。

その他の回答 (4)

  • leaz024
  • ベストアンサー率75% (398/526)
回答No.4

> 文字列がASCIIか判定する方法はないのでしょうか。 getcode が undef を返す条件は ・日本語が含まれない時 ・sjis か euc か判断できない時 の2通りしかありません。 1つ目の「日本語が含まれるかどうか」は、「\e 及び \x80 ~ \xFF」が含まれるかどうかで判断しています。(\e は JIS で使われるエスケープコード) 幸いなことに、これらの文字を含まない日本語コードは存在しないようなので、日本語が含まれないと判断されたら ASCII だと考えてよいでしょう。 2つ目の条件と区別するには、getcode をリストコンテキストで呼び出し、戻値の1番目の値を 0 と比較します。   ($matched, $icode) = jcode::getcode(\$line);   if (! defined $icode) {     if ($matched == 0) { print 'ASCII' }     else { print 'sjis or euc' }   } ちなみに上記の文字が含まれていれば、それは 'jis', 'sjis', 'euc', 'binary' のどれかだと判断されます。 これは「未知の文字コードかどうかは判断できない」ということであり、試しに unicode の「日本語」という文字列を渡してみても 'sjis' という結果が返ってきます。 > getcode,convertの判定・変換結果に多用されるASCIIがないのはなぜだと思われるかも可能だったら教えていただきたいです。 そもそも jcode.pl は日本語変換ライブラリなわけで、何の変換処理も必要としない ASCII をわざわざ覚えておく必要もないと考えたのではないでしょうか。 また、convert は文字コードが偽であるかどうかを真っ先に調べていますが、この時   return if $icode eq 'ascii'; とするより   return unless $icode; とした方が効率も良さそうですからね。 注:実際のコードとは異なります。

noname#6323
質問者

補足

ご回答ありがとうございます。 実際にleaz024さんのコードを使って試してみたところ 動作の確認が取れ、理解できました。 再三の質問になってしまい大変申し訳ないのですがundef=ヌルという認識でいたので ASCII時に返されているのはヌルだとおもっていたのですがdefinedはヌル・0・空配列の時に真で 未定議時に偽とみたのでundef != ヌルという認識でよろしいのでしょうか。 結果とdefinedの定義からするとundef != ヌルなのですがなんとなく'未定義'を返すという のが変わっている(?)と感じたので確認させていただきたいと思いました。 参考:http://tohoho.wakusei.ne.jp/wwwperl2.htm#defined

  • leaz024
  • ベストアンサー率75% (398/526)
回答No.3

getcode の戻り値は 'jis', 'sjis', 'euc', 'binary' 及び undef のいずれかです。 文字コードが判別できなければ undef が返ります。 > なんらかの出力が得られるとWebで見た これは undef まで含めた広い意味で書かれたか、そうでなければ出所の内容が間違っているのでしょう。 単なるアスキー文字列は 'JIS' でも 'シフトJIS' でも 'EUC' でもないので、当然「判別不能」という結果になります。 > その対策も知りたい とのことですが、対策というからには「getcode が undef を返すことに問題がある」ということですよね? 私も長らく jcode.pl を使っていましたが、これが問題となったことはありません。 ですが、もしその辺を補足もらえれば、アドバイスのしようもあるかと思います。 (ちなみに jcode.pl に含まれる関数で、これが問題となるものはありません。) jcode.pl については、参考URLの「jcode.pl の私的な解説書」も参考にされるとよいでしょう。

参考URL:
http://www.mikeneko.ne.jp/~lab/kcode/jcode.html
noname#6323
質問者

補足

詳細な回答ありがとうございます。 >単なるアスキー文字列は 'JIS' でも 'シフトJIS' でも 'EUC' でもないので、当然「判別不能」という結果になります。 ここがわかっていなかったようです。 >>その対策も知りたい これは「簡単な文字列なのだから'jis','sjis','eus'のいずれかになるはず。undefになるのはバグもしくは 使い方の間違いをしたため」と勘違いしていたための質問でした。 その答えは「getcodeはASCIIでundefになる仕様だからundefを返すのは当然で正常である」ということだと わかりました。 私が「対策も知りたい」と考えたのはASCII文字列が ASCII文字列であるという確認をgetcodeで得たいと思ったためです。 ある文字列がASCIIのような汎用的な文字コードであるかそれ以外の不明な文字コードであるのかが判断したいです。 getcodeにおいてはASCIIは「その他の文字コード」に 分類されますが、文字列がASCIIか判定する方法はないのでしょうか。 getcode,convertの判定・変換結果に多用されるASCIIがないのはなぜだと思われるかも可能だったら教えていただきたいです。

noname#25358
noname#25358
回答No.2

 他の半角文字や長文の半角文字で成功するかどうか確認してください。  その場合、文字列が短すぎて判定材料がないためであると思われます。  他の文字でも失敗する場合には、単に半角文字の文字コードは「アスキーだから」と決まってるせいでしょう。

noname#6323
質問者

お礼

文章が長くても同様にヌルでした。 おっしゃる通り原因はASCIIだからということのようです。判定結果にASCIIがないということを理解していませんでした。 大変助かりました。ありがとうございました。

noname#25358
noname#25358
回答No.1

 それは出力がないのではありません。  ヌル文字列が出力されているのです。ヌル文字列もれっきとした出力です。  よって、   if ( $code eq '' ) { .... }  とでもやれば、文字コード判定に失敗したかどうかを知ることができます。

noname#6323
質問者

補足

回答ありがとうございます。 15日にレスをしたのですが失敗していたようです。 すみません。 getcodeにヌル出力があるということを知りませんでした。ありがとうございます。 当初の質問とずれがあるかもしれませんが「a」という 非常に単純な文字コード判定に失敗している 原因はなんでしょうか。Webを見て使用例にあるような「a」の判定ができない原因 を知りたいです。またその対策も知りたいです。 よろしくお願いいたします。

関連するQ&A

  • jcode.plについて

    次のエラーが発生します。 Undefined subroutine &jcode::convf called at ./jcode.pl line 291. カレントに、jcode.plを置いているだけでは動作するのでしょうか? また、Jcode.pmを使った場合、 &Jcode::convert(\$test_sjis, "sjis"); と大文字にしないといけないのですが、これは仕方ないことでしょうか? てっきり、 require './jcode.pl'と use Jcode.pmの差し替えで済むと思っていました。 #!/usr/bin/perl require './jcode.pl'; my $test = "パソコン結構です。"; #文字化けチェック用 my $test_sjis = $test; my $test_ujis = $test; my $test_jis = $test; &jcode::convert(\$test_sjis, "sjis"); &jcode::convert(\$test_ujis, "ujis"); &jcode::convert(\$test_jis, "jis"); print "\$test_sjis=[$test_sjis]\n"; print "\$test_ujis=[$test_ujis]\n"; print "\$test_jis =[$test_jis]\n"; exit; __END__

    • ベストアンサー
    • Perl
  • Jcodeで変換できません。。。

    下記のCGI(文字コードはutf-8)を作成したのですが、正常に表示されません。 ~を上手に判定できていないということでしょうか??? また、もし、正しく変換できないのであれば、Jcodeで変換できない文字の一覧などあれば助かります。 分かる方、何卒、宜しくお願い致します。 #!/usr/bin/perl print "Content-type: text/html;charset=Shift_JIS\n\n"; $str = "1~10"; use Jcode; Jcode::convert( \$str,"sjis","utf8"); print $str; 表示された結果 1?10 となりました。

    • ベストアンサー
    • Perl
  • jcode.plのバグでしょうか?KCctchでの質問です。

    PerlのプログラムをKCatch.pmで調べていましたが。 次のような表示がされました。 jcode.plのバグでしょうか?プログラムに問題があるのでしょうか? お教えいただければ幸いです。 ../data/clients.txtが開けません。 Catch: Thu Jun 21 08:54:31 2001 -------------------------------------------------------------------------------- [jcode.pl:366:warn] Use of uninitialized value at jcode.pl line 366. > sub max { $_[ $[ + ($_[$[] < $_[$[+1]) ]; } [jcode.pl:362:warn] Use of uninitialized value at jcode.pl line 362. > $code = ('euc', undef, 'sjis')[($sjis<=>$euc) + $[ + 1]; -------------------------------------------------------------------------------- anquit.cgi with Perl 5.00502 for freebsd

    • ベストアンサー
    • Perl
  • Jcode.pmでconvertできない

    あけましておめでとうございます。 早速ですが、皆様のお力を拝借したく。 WindowsXPSP2+ActivePerl5.6.1でJcode.pmを使用して、utf8へ変換しようとしました。 http://okwave.jp/qa2600582.html を参考にJcode.pmを導入し(とある事情でインストールしておりません)、以下のソースを記述しました。 ちなみに"sjis"で記述しております。 #!/usr/local/bin/perl use lib "./lib"; use Jcode; $buf = "てすてすてす"; print "BeforeCode=".Jcode::getcode($buf)."\n"; Jcode::convert( \$buf, "utf8"); #$j = Jcode->new($buf); #$buf = $j->utf8; print "$buf\n"; print "AfterCode=".Jcode::getcode($buf)."\n"; exit; すると BeforeCode=sjis AfterCode=euc と表示され、"utf8"を指定したにも関わらず、"euc"に変換されてしまいました。 次に、上記ソースの中ほどを #Jcode::convert( \$buf, "utf8"); $j = Jcode->new($buf); $buf = $j->utf8; と書き換えてみました。すると、 BeforeCode=sjis Undefined subroutine &Jcode::_Classic::euc_utf8 called at lib/Jcode/_Classic.pm line 255. とエラーが出てしまいます。 見た感じeuc_utf8が存在しないと言われているようですが、Jcode\Unicode\NoXS.pmに存在しています。 環境に問題があるような気はしますが、どのようにすれば"utf8"への変換が成功するのでしょうか?ご教授いただければ幸いです。 ちなみに上記ソースで Jcode::convert( \$buf, "jis"); Jcode::convert( \$buf, "euc"); Jcode::convert( \$buf, "sjis"); はすべて成功し、指定した文字コードに変換されました。 "utf8"への変換だけが失敗するという状況で、新年早々頭を抱えております。

    • ベストアンサー
    • Perl
  • perl jcode::convert 半角>全角

    perlでjcode::convertで 半角を全角に変換すると 正しく変換される時とされない時があります。 例えば、 sample1.plとsample2.plの my $message = 'の次の「ハンカク」の4文字は半角の文字です。 (注)ここにアップロードすると全角で表示されてしまいます。   この4文字を半角にして確認してください。 sample1.plではこの4文字が全角に変換されるのですが sample2.plではこの4文字は半角のままです。 なぜ全角に変換されないのでしょうか。 (Windows7, ActivePerl v5.16.3) ---sample1.pl------------ require "jcode.pl"; my $message = 'ハンカク文字は使えるかな?'; jcode::convert(\$message,"sjis","", "z"); print "$message\n"; --------------- ---sample2.pl------------ require "jcode.pl"; my $message = 'ハンカク文字'; jcode::convert(\$message,"sjis","", "z"); print "$message\n"; --------------- なお、どちらも以下のようなメッセージが表示されています。 これは何を意味しているのでしょうか。 defined(%hash) is deprecated at C:/Perl64/site/lib/jcode.pl line 684. (Maybe you should just omit the defined()?) defined(%hash) is deprecated at C:/Perl64/site/lib/jcode.pl line 693. (Maybe you should just omit the defined()?)

    • ベストアンサー
    • Perl
  • jcodeでsjisに変換できない

    メールのSubjectを取得するスクリプトを作っています。 Subjectを取得し、iso-2022をsjisに変換して表示したいのですが、変換できません。 以下、どこに問題ありますでしょうか? すみません、他人の作ったものを修正しているので、よく理解していない部分が多いです。 #--------------------------------------------- require 'jcode.pl'; $subject = 'Subject: =?iso-2022-jp?B?GyRCJWEhPCVrJE4lRiU5JUgbKEI=?='; &jcode'convert(*subject, 'sjis'); print "-->$subject\n"; #--------------------------------------------- これをWindowsのDOSプロンプトから実行しても、以下のようにShift-JISに変換されていません。 c:\test>perl test.pl -->Subject: =?iso-2022-jp?B?GyRCJWEhPCVrJE4lRiU5JUgbKEI=?= 環境 Perl v5.8.8 WindowsXP(sp2) 以上、よろしくお願いします。

    • ベストアンサー
    • Perl
  • jcode.pl

    日記などのスクリプトを作成しているのですが、とりあえず今まで、そこまでの理由もわからず他のスクリプトに習ってjcode.plをデコード処理部で &jcode'convert(*value,'sjis'); &jcode'convert(*name,'sjis'); のように使ってきました。 ですが、たまたま今回、jcode.pl等を書き忘れてしまったのですが、ブラウザから投稿してみても文字化けという文字化けが起こりません。スクリプト自身はsjisで書いています。ログファイルもどうやらsjisコードで書き込まれているようなのですが、それでもjcode.plは必要なのでしょうか。windows XP にApache + Active Perl での動作と、@niftyで設置して動作を確認しました。 この場合、jcode.plは必要あるのでしょうか?

    • ベストアンサー
    • Perl
  • jcode'convertについて

    以下のようなプログラムを書きました。 -------------------------------------------------------------- require 'jcode.pl'; @a=("ら","ー","め","ん"); @b=("半","ら","い","す"); foreach $a(@a){ &jcode'convert(*a, "sjis"); foreach $b(@b){ &jcode'convert(*b, "sjis"); print $a; print $b; $aaa = <STDIN>; } } ------------------------------------------------------------------ &jcode'convert(*a, "sjis");が無いときは'ら半','らら','らい',,'らす','ー半'… といくのですが、&jcode'convert(*a, "sjis");をつけると'らす'でプログラムが終わってしまい、'ー半'…以降がプリント出来ません。 どうすればよいのでしょうか。またどうしてこうなるのでしょうか。

  • cgi出力での文字コードについて

    下記のソースをsjisで作っていて、出力するdata.txtをuft-8で保存したいです。 どのようにすればよいでしょうか? 下記ソースでは、data.txtはsjisになっています。 尚、htmlはsjisなのでそのまま使用したいです。 どなたか教えてください。 宜しくお願いします。 ############################# #!/usr/local/bin/perl require 'jcode.pl'; require 'cgi-lib.pl'; &ReadParse; $datafile='data.txt'; ←これの保存のみutf-8にしたい open(FH,">$datafile"); print FH "$in{'name'}"; close(FH); rint "Content-type:text/html\n\n"; print "<meta http-equiv='Content-Type' content='text/html; charset=Shift_JIS'>"; print "<html><head></head><title>テスト</title><body>\n"; print "<center>入力完了しました。</center><hr /><br>\n"; print "<b>名前:</b>$in{'name'}<br>\n"; print "<hr />\n"; print "</body></html>";

    • 締切済み
    • CGI
  • IIS の@INC ERRORについて教えて

    wiin8にIISとPerl64をインストールしました。「Default Web Site」を「C:\wabs」に設定。 tst.cgi #!/usr/local/bin/perl print "Content-Type: text/html", "\n\n"; print "<HTML>\n"; print "<BODY>\n"; print "こんにちは!<BR>\n"; print "</BODY>\n"; print "</HTML>\n"; で、無事に動いてると確認したのですが、 C:\wabs\lib\jcode.pl を設置して、 require './lib/jcode.pl'; として、実行すると ERROR = Can't locate ./lib/jcode.pl in @INC (@INC・・・・ と、 パスが通っていないようなメッセージが出て、解決策が解らず困っています。 どなたか、解決策を教えてください。よろしくお願いします。

専門家に質問してみよう