- ベストアンサー
文字列比較ができない問題について
- PerlのCGIスクリプトで文字列比較ができない問題が発生しています。
- フォームに入力された値とファイルに書かれた名前を比較し、一致しなければエラーメッセージを表示する仕組みです。
- しかし、正しく動作せず、「名前がありません」というメッセージが表示されません。初心者のため、どこが間違っているのかわかりません。
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
まず > 『name.log』(604) > takeshi > masako-nisimura > teru009 > ....以下、10種ほど似たような物 これですが、一つのデータは一行で入ってますよね? 次に、 > open(DB,$file); > @HIKAKU2 = <DB>; > close(DB); ここで、一行のデータが一要素として、@HIKAKU2 に入りましたね? > print "Content-type: text/plain\n\n"; > > > foreach $i (@HIKAKU2) > { ここの $i (@HIKAKU2 の中の一つの要素) ですが、改行が末尾に必ず付きます。なので、 > if($i eq $ck) { $sain++; } $ck の末尾も開業であったり等、1 バイトもたがわぬ確実な場合にのみ、$sain がインクリメントされます。 > } > > if ($sain != 1) { print "名前がありません"; } > > __END__ で、気になるのが、 > こちらの考えでは、name.logの中で同じ名前はないので、$sainには1しか入らず、 > したがって、名前がなかった場合は「名前がありません」が表示されるはずなのですが、どうもそれがうまく動きません。 うーんと、name.log の中に同じ名前はないのなら、$sain はインクリメントしませんよね?だから 1 しか入らずって事はないでしょう。 とりあえず、末尾の改行を取って試してください。 foreach $i (@HIKAKU2) { chomp $i; if($i eq $ck) { $sain++; } } こういう風に。 ちなみに、これらの致命的だなと感じる部分は > @HIKAKU2 = <DB>; これで何バイト (何メガバイト、何ギガバイト) あろうがかまわずいっぺんに配列要素に突っ込んでるとこ。(特に CGI なら、自分の意図しないところでログが膨大な量になる可能性だって「無いとは言い切れません」から) 次に、 > foreach $i (@HIKAKU2) > { > if($i eq $ck) { $sain++; } > } これの目的は、あるか無いかをチェックしているだけ。仮に @HIKAKU2 が 1 万要素ある配列だとして、比較を行う際に @HIKAKU2 の先頭要素 ($HIKAKU2[0]) が $ck と一致したとしたら、@HIKAKU2 のそれ以降のほかの要素との比較 (9,999 回分の無駄な処理) が行われること。 これらを、もっとよくするための提案 print "Content-type: text/plain\n\n"; open(DB,$file); while(<DB>) { chomp; if($_ eq $ck){ $sain++; last; } } close(DB); if ($sain != 1) { print "名前がありません"; } あくまで、提案ですがね。
お礼
回答ありがとうございました。 確かに、@HIKAKU2 = <DB>についてはログが膨大になる可能性が考えられますね。 こういった処理をする場合には充分、注意しておきたいと思います。 また、一致する物が見つかった時点でクローズする、という方法はなるほど、すごくスマートだと思いました。 まだまだ勉強不足でした・・・もっと精進したいと思います。(^^;)
補足
あ、ちなみに呈示いただいた文例できちんと動作しました。 ありがとうございます!