• ベストアンサー

if文中で@***(配列変数)って・・・。

if文中で配列変数って使用できるのでしょうか? やりたいことは、 フォームを使って入力されたデータと、ログファイルの中身を1行ずつ比べて、 同じものがあったら、そこで比較を終了させる、というようなことをやりたいのです。 たとえでこんな感じでif文つくりました。(これもあってるかどうか微妙なのですが。) for($i=0; $i<5){ @FILELOG2 = split(/&/,$FILELOG[$i]); if (@FILELOG2 eq @log){ print "ok\n"; }else{ print "ng\n"; } exit; } フォームを使って入力されたデータは、 read(STDIN,$buffer,$ENV{'content_length'}); $buffer =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; @log =split(/&/,$buffer); のような感じで処理してあります。 ログファイルは #ログファイルをオープン。 open FILE,"<02.log"; flock(FILE,2); @FILELOG=<FILE>; flock(FILE,8); close FILE; のようにしてあります。 おわかりの方、よろしくお願いします。

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

  • ベストアンサー
  • HUTABA
  • ベストアンサー率27% (436/1611)
回答No.3

#1です。 >FILELOG2の前の#は何を意味するものなのでしょうか? $#FILELOG2は、@FILELOG2の最後の添え字を返します。 例えば@FILELOG2の要素数が3だった場合は、2を返します。 >合っているところまでそれぞれの値を表示し、止まるのですが、 >「あってるよ」が表示されません。 >なぜでしょうか? 横レスで申し訳ありませんが、ログファイルの方には改行が含まれていませんか? 例えば $SYOZOKU1 が "所属" $SYOZOKU2 が "所属\n"の場合、表示すると一見同じに見えますが改行が入っているので if ($SYOZOKU1 eq $SYOZOKU2) はヒットしません。 $SYOZOKU2の改行をあらかじめ取っておくなりすれば良いと思いますよ。

KODAMAR
質問者

お礼

回答ありがとうございます。 >$#FILELOG2は、@FILELOG2の最後の添え字を返します。 ありがとうございます、理解できました。 >$SYOZOKU2の改行をあらかじめ取っておくなりすれば良いと思いますよ。 @FILELOG2 = split(/&/,$FILELOG[$i]); @FILELOG2 = ~ s/\n//g; のようにしてみましたが、やはりダメでした。 改行をとるというのはこういうことではないのでしょうか? よろしくお願いします。

その他の回答 (3)

  • HUTABA
  • ベストアンサー率27% (436/1611)
回答No.4

#1、#3です。 @FILELOG2 = ~ s/\n//g; ではなくて、 for文の中で $FILELOG[$i] =~ s/\n$//; @FILELOG2 = split(/&/,$FILELOG[$i]); として下さい。 \n$ の "$" は正規表現で文末を意味します。 この場合、文末の\nだけを削除します。

KODAMAR
質問者

お礼

回答ありがとうございます。 文末には「$」を使うんですね。 知りませんでした。 無事「あってるよ」が出力されました。 ありがとうございました。

KODAMAR
質問者

補足

また教えていただきたいのですが、 print "Content-type:text/html\n\n"; $flag = 0; for($i=0;$i<$#FILELOG && $flag==0;$i++){ $FILELOG[$i] =~ s/\n$//; @FILELOG2 = split(/&/,$FILELOG[$i]); ($BANGOU2,$NAME2,$SYOZOKU2) = split(/&/,$FILELOG[$i]); ($BANGOU2TITLE,$BANGOU2) = split(/=/,$BANGOU2); ($NAME2TITLE,$NAME2) = split(/=/,$NAME2); ($SYOZOKU2TITLE,$SYOZOKU2) = split(/=/,$SYOZOKU2); print "$flag$flag<BR>\n"; print "$i$i<BR>\n"; print "BANGOU1は「$BANGOU1」<BR>\n"; print "NAME2は「$NAME1」<BR>\n"; print "SYOZOKU1は「$SYOZOKU1」<BR>\n"; print "<BR>\n"; print "BANGOU2は「$BANGOU2」<BR>\n"; print "NAME2は「$NAME2」<BR>\n"; print "SYOZOKU2は「$SYOZOKU2」<BR>\n"; print "<BR><HR>\n"; if($BANGOU1 eq $BANGOU2 && $NAME1 eq $NAME2 && $SYOZOKU1 eq $SYOZOKU2){ print "あってるよ\n"; } #終わらせたい時は $flag を 1 にする } としていますが、ログファイルの2行目まで(iが1まで)しか動作しません。 なぜでしょうか?

  • duckling
  • ベストアンサー率47% (88/185)
回答No.2

> if (@FILELOG2 eq @log){ ↑これだと、両方の配列の数が同じだったらtrueが返ります。 if文で配列丸ごとゴッソリ 「中身がまったく同じだったら」という一発比較は、 どの言語であっても出来ないと思いますよ。 ($a,$b,$c) = split(/&/,$FILELOG[$i]); と、変数に格納してから if($a eq $log[0] && $b eq $log[1] && $c eq $log[2]){ print "OK"; } とした方がいいです。 > そこで比較を終了させる をやりたい場合は、 $flag = 0; for($i=0;$i<$#FILELOG && $flag==0;$i++){ #終わらせたい時は $flag を 1 にする } として、$flagが0の間だけfor回しを行う、 という風にしたらいいのではないでしょうか。

KODAMAR
質問者

お礼

回答ありがとうございます。 ご指摘とおり、こんな感じにしてみました。 #フォームで送られてきたデータを分割 ($BANGOU1・$NAME1・$SYOZOKU1) ($BANGOU1,$NAME1,$SYOZOKU1) =split(/&/,$buffer); ($NAKAMITITLE,$BANGOU1TITLE,$BANGOU1) = split(/=/,$BANGOU1); ($NAME1TITLE,$NAME1) = split(/=/,$NAME1); ($SYOZOKU1TITLE,$SYOZOKU1) = split(/=/,$SYOZOKU1); #ログファイルを分割 ($BANGOU2・$NAME2・$SYOZOKU2) ($BANGOU2,$NAME2,$SYOZOKU2) = split(/&/,$FILELOG[$i]); ($BANGOU2TITLE,$BANGOU2) = split(/=/,$BANGOU2); ($NAME2TITLE,$NAME2) = split(/=/,$NAME2); ($SYOZOKU2TITLE,$SYOZOKU2) = split(/=/,$SYOZOKU2); それをfor文でループさせる。 print "Content-type:text/html\n\n"; $flag = 0; for($i=0;$i<$#FILELOG && $flag==0;$i++){ @FILELOG2 = split(/&/,$FILELOG[$i]); ($BANGOU2,$NAME2,$SYOZOKU2) = split(/&/,$FILELOG[$i]); ($BANGOU2TITLE,$BANGOU2) = split(/=/,$BANGOU2); ($NAME2TITLE,$NAME2) = split(/=/,$NAME2); ($SYOZOKU2TITLE,$SYOZOKU2) = split(/=/,$SYOZOKU2); print "$BANGOU1<BR>\n"; print "$NAME1<BR>\n"; print "$SYOZOKU1<BR>\n"; print "<BR>\n"; print "$BANGOU2<BR>\n"; print "$NAME2<BR>\n"; print "$SYOZOKU2<BR>\n"; if($BANGOU1 eq $BANGOU2 && $NAME1 eq $NAME2 && $SYOZOKU1 eq $SYOZOKU2){ print "あってるよ\n"; } #終わらせたい時は $flag を 1 にする } としてみました。 合っているところまでそれぞれの値を表示し、止まるのですが、 「あってるよ」が表示されません。 なぜでしょうか? よろしくお願いします。

  • HUTABA
  • ベストアンサー率27% (436/1611)
回答No.1

>if (@FILELOG2 eq @log) このif文だと、KODAMARさんの期待通りの動作はしません。 この場合、@FILELOG2と@logの要素数を比較し、同じ数であればtrueを返します。 >フォームを使って入力されたデータと、ログファイルの中身を1行ずつ比べて、 >同じものがあったら、そこで比較を終了させる、というようなことをやりたいのです。 であれば、 for ($i=0; $i<=$#FILELOG2; $i++) {  if ($FILELOG2[$i] eq $log[$i])  {   print "OK";  }  else  {   print "NG";  } } と、素直にループを回した方が良いですよ。

KODAMAR
質問者

お礼

回答ありがとうございます。 このままコピーして貼り付けてみたのですが、エラーが返ってきてしまいました。 なぜでしょうか・・・? >for ($i=0; $i<=$#FILELOG2; $i++) FILELOG2の前の#は何を意味するものなのでしょうか? よろしくお願いします。

関連するQ&A