記事内容に返信したいのですが?

[上に] [前に] [次に]
やす 1999/05/01(土) 14:27:06
BBS投稿者の発言、
投稿内容を呼び出し、その内容にレスを付けたいのですが(投稿された同じ欄に)。
ログfile.txtから必要な記事を取り出すには>
取り出した記事に返信コメントを書き、
再び投稿者記事、返信コメントを基の場所に
              出力するには>
誰か教えてください。

exon 1999/06/23(水) 03:06:54
コメント挿入は流行りの掲示板のスタイルですね。YY-Boardとか。
単純に本文にレスを書き加えてしまえばよさそうな気がしますが。

やす 1999/06/25(金) 15:48:53
書き込み後、約2ヶ月・・・。
exonさん Reありがとうございます。
それからというもの悩みは解決していません、あセあセ。
>単純に本文にレスを書き加えてしまえばよさそうな気がしますが。
ログファイルを取り出し追加すればよいわけですよね。
一番さんのコメント
二番さんのコメント
三番さんのコメント
順序ずけされている配列から三番さんのコメントだけを取り出す
事ができません。
たびたびすみませんが、答えというより答えに近いヒントを下されば
幸いです。
こんな事も分からないのかと笑われてしまうかもしれませんが、
perlを勉強するにあたって、こんな事が僕にとって必要なので、
よろしくお願いします。

じぇい 1999/06/25(金) 16:06:01
例えば、あらかじめそれぞれのコメントに認証番号のようなものをつけておいて、hiddenなどでその番号を隠し持っておく、、などという方法はどうでしょうか?

(そういうことではないのですか?)

やす 1999/06/25(金) 16:17:40
じぇいさん!早速ありがとうございます。
>(そういうことではないのですか?)
そういう事だと思います。
すみません自信がなくて。
認証番号とは記事番号とか、個々のパスワードと言うことで解釈し
早速取り組んでみます。
じぇいさんありがとうございます。

じぇい 1999/06/25(金) 16:46:23
ちなみに、、

open(IN, "$bbs_data");
flock(IN, 2);
$befo_data = <IN>;
flock(IN, 8);
close(IN);


#
# 二重投稿防止
#
($k_msg,$k_name,$k_mail,$k_url,$k_date,$k_addr,$count) = split(/,/, $befo_data);
if($ENV{'REMOTE_ADDR'} eq $k_addr && $k_msg eq $f_msg){
&error('同一人の連続投稿は禁止です。');
}

#
# 削除に使う識別番号のカウントアップ
#
if($count){
$count++;
} else{
$count = 1;
}

#
# すべてのデータをひとつにまとめる
#
$new_data = "$f_msg,$f_name,$f_mail,$f_url,$date,$ENV{'REMOTE_ADDR'},$count,\n";

僕はこんな感じで番号をつけています。(ついでに2重投稿防止もできるし。2重投稿防止については、もっと堅くできると思いますが。)

やす 1999/06/26(土) 09:18:14
じぇいさんREありがとうございます。
なんとか別ログで記事NOをつけられました。
#登録FORM
print "<FORM METHOD=POST ACTION=××.cgi>\n";
print "<INPUT TYPE=text NAME=name>\n";
print "<TEXTAREA NANE=coment CLOSE=7 ROWS=40></TEXTAREA>\n";
print "<INPUT TYPE=hidden NAME=action VALUE=enter>\n";
print "</FORM>\n";

#別ログで記事NOを所得して見ました。うまく認証番号がつけられました。

#出力結果
print "<FORM METHOD=POST ACTION=××.cgi>\n";
print "記事NO$number\n";
print "$nameさん\n";
print "<BLOCKQUOTE>$coment</<BLOCKQUOTE>\n";
print "<INPUT TYPE=hidden NAME=action VALUE=res>\n";
print "<INPUT TYPE=hidden NAME=number VALUE=$number>\n";

#検索マッチを使って記事を拾い出して見ました。
if (!open(LOG, "$logfile") {&error;}
@DATA=<LOG>;
close(LOG);
foreach $data (@DATA) {
    push (@kensaku, $data) if ($data =~ $number); }

#検索結果
print "@kennsaku\n";

と、言った感じでやって見ました。
1@kensakuにうまくマッチしてくれません。
 (うまく拾えるものとうまく拾えないのがあります)
2@kensakuに入った配列を分解することはできないのでしょうか。
 (僕が思うにただコピーされているだけだと思います)
3これがうまくいけば本文に追加書き込みできるのでしょうか。

じぇい 1999/06/26(土) 13:39:50
>@kensakuにうまくマッチしてくれません。
if ($data =~ $number)
この方法では、、明らかにうまくいきませんよね?($dataというのはすべてのデータを表しているんですよね?)
もし、メッセージ文中などに認証番号と同じ文字列が含まれていたら、本当の記事に当たる前にそれがマッチしてしまいますよね?

>@kensakuに入った配列を分解することはできないのでしょうか。
、、というのは?、具体的にどのような処理を行いたいのでしょうか?


あと、僕の場合は、、1から総なめ(でも別にいいのですが、、)をするのではなく、hiddenで、認証番号と同時に、そのデータを読み込んだときに、そのデータがファイルの何番目にあったかという記憶もhiddenで隠し持っておいて、大たい1発か2発で(foreachを使うのではなく、whileを使って)見つかるようにしています。

例えば、、これは削除処理なのですが、、(基本は同じですね。)

$i = --$FORM{'DELETE'};

while(@all_msg >= $i)
{
($f_msg,$f_name,$f_mail,$f_url,$date,$addr,$count) = split(/,/, $all_msg[$i]);
if($count == $FORM{'CHECK'}){
splice(@all_msg, $i, 1);
open(OUT, "+< $bbs_data");
flock(OUT, 2);
truncate(OUT, 0);
seek(OUT, 0, 0);
print OUT @all_msg;
close(OUT);
&read_msg;
}
$i++;
}

このようにして、あらかじめある程度の見当をつけておきます。
削除処理を行おうとしている間に誰かが書きこみをしていた場合を想定して、ループ処理を行っています。
僕の場合は、メッセージの削除は管理人しか行えないようにしているので、これでうまくいきますが、削除処理が誰でも行えるのであれば、もう少し工夫が必要化もしれません。

やす 1999/06/26(土) 15:00:03
じぇいさんREいつもありがとうございます。

>この方法では、、明らかにうまくいきませんよね?($dataというのはすべてのデータを表しているんですよね?)
たしかに$numberに一致したすべてにマッチしてしまいました。
>認証番号と同時に、そのデータを読み込んだときに、そのデータがファイルの何番目にあったかという記憶もhiddenで隠し持っておいて・・。
すみません・・もう少し具体的におねがいできないでしょうか。
>$i = --$FORM{'DELETE'};
意味はだいたいわかるのですが<FORM></FORM>内のどの部分にあたるのでしょうか。

>if($count == $FORM{'CHECK'}){
と言うのは僕の場合
<INPUT TYPE="hidden"NAME="CHEKE"VALUE="$number">
でよいのですか。

じぇい 1999/06/26(土) 15:31:51
え〜と、、ちょっと長くなりますが、、。

データの保存方法が僕といっしょとは限らないので、そこらへんは微調整してください。

あくまで、僕が取っている方法なので、これが最も正しい方法かどうかはわかりませんが、、。

これは、削除処理の場合です。(前にも書きましたが、基本は同じですね。)

open(IN, "$bbs_data");
flock(IN, 2);
@show_datas = <IN>;
flock(IN, 8);
close(IN);

$i = 0;
foreach $show_data (@show_datas)
{
  $i++;
  ($f_msg,$f_name,$f_mail,$f_url,$date,$addr,$count) = split(/,/, $show_data);
  print "<FORM METHOD=POST ACTION=\"$easy_master\">\n";
  print "<table width=420><tr><td><INPUT TYPE=submit VALUE=\" 削除 \"></td></tr>\n";
  print "<INPUT TYPE=hidden NAME=DELETE VALUE=$i>\n";
  print "<INPUT TYPE=hidden NAME=CHECK VALUE=\"$count\">\n";
  print "</FORM>\n";
  print "<table>(以下略)</table>\n";
}

データを配列の頭から順に表示させていく場合、削除処理を行おうとしたとき、そのデータが配列の何番目に格納されていたかを$iに保存しておきます。
$countは認証番号です。

そして、、実際の削除処理は上記の通り、、

open(IN, "$bbs_data");
flock(IN, 2);
@all_msg = <IN>;
flock(IN, 8);
close(IN);


$i = --$FORM{'DELETE'};

while(@all_msg >= $i)
{
  ($f_msg,$f_name,$f_mail,$f_url,$date,$addr,$count) = split(/,/, $all_msg[$i]);
  if($count == $FORM{'CHECK'}){
     splice(@all_msg, $i, 1);
     open(OUT, "+< $bbs_data");
     flock(OUT, 2);
     truncate(OUT, 0);
     seek(OUT, 0, 0);
     print OUT @all_msg;
     close(OUT);
     &read_msg;
  }
  $i++;
}

というように行います。
こうすれば、配列の頭から一つ一つ探していかなくて済みます。
要するに処理を軽くするための手段です。

$i = --$FORM{'DELETE'};

”--”の意味は、上のコードをよく見てもらえばわかります。

>と言うのは僕の場合
><INPUT TYPE="hidden"NAME="CHEKE"VALUE="$number">
>でよいのですか。
え〜と、、どのようにしてデータを保存しているのでしょうか?

ふじ 1999/06/26(土) 15:35:44
#本筋と関係ないところで済みませんが。

>open(IN, "$bbs_data");
>flock(IN, 2);
>@all_msg = <IN>;
>flock(IN, 8);
>close(IN);

これだとロックしている意味がありませんよ。以下を参照のこと。
http://www.tohoho-web.com/wwwperl4.htm#Flock
http://www.tohoho-web.com/wwwperl2.htm#flock

じぇい 1999/06/26(土) 15:38:17
補足。

>”--”の意味は、上のコードをよく見てもらえばわかります。
$i++の処理をデータを書き出す前じゃなくて後でやったら”--”を尽ける必要はないのですが、、条件判断(削除処理を行うかどうか)のときに
if($FORM{'DELETE'}){...}
とやっていたので、$i++をデータを書き出す前にやる必要がありました。、、しかし、、よく考えてみたら、、
if($FORM{'CHECK'}){...}
、、とやっていたら、、よかったような気が。。^^;

まあ、、どうでもいいことです。気にしないでください。(笑)

じぇい 1999/06/26(土) 15:40:38
>これだとロックしている意味がありませんよ。

…どういう意味でしょうか?

flock(IN, 2);
この部分について言っているのでしょうか?

じぇい 1999/06/26(土) 15:56:45
まあ、、しかし、、保存件数が100件かそこらなら、、普通にforeachを使って総なめをしても全然問題ないと思いますが…。。

ふじ 1999/06/26(土) 15:57:45
>…どういう意味でしょうか?
よく読んでなかったです。読込み時だったら問題ないですね(^^;
失礼いたしました。

やす 1999/06/26(土) 16:01:16
じぇいさんREありがとうございます。
さっそく取り組んでみます。

ふじさん補足コメントありがとうございます。
if (!open(LOG, "+<logfaile"){&error;}
eval 'flock(LOG,2);';
@data=<LOG>;
eval 'flock(LOG,8);';
close(LOG);
と僕の場合していますが・・。

じぇい 1999/06/26(土) 16:09:39
>if (!open(LOG, "+<logfaile"){&error;}
読みこむだけならば、、

if (!open(LOG, "logfaile"){&error;}

ですね。

書き込み時には、

     open(OUT, "+< $bbs_data");
     flock(OUT, 2);
     truncate(OUT, 0);
     seek(OUT, 0, 0);
     print OUT "...";
     close(OUT);

とする必要がありますね。

ふじ 1999/06/26(土) 16:16:26
話が逸れて行く・・・

>まあ、、しかし、、保存件数が100件かそこらなら、、普通にforeachを使って総なめをしても全然問題ないと思いますが
保存件数が数万件だったら、一気に配列に読み込むのはヤバいような(環境によりますが)

>eval 'flock(LOG,2);';
これ、flockを実装していない機械の場合、ロック機構が全く働かないから(知らん顔して実行する)怖いですね(^^;
自宅でWindows環境などでデバッグするための処置だとは思いますが。
万が一NTがサーバの場合は気を付けないと。念の為。

じぇい 1999/06/26(土) 16:30:29
>保存件数が数万件だったら、一気に配列に読み込むのはヤバいような(環境によりますが)
もちろんです。(笑)

やす 1999/06/27(日) 10:45:36
   トチュウケイカです。

削除処理はできました。
(恥ずかしい話、ちょっとビックリしています)。
もう少しでできるような気がします、頑張ってつづけます。以上。

やす 1999/06/27(日) 10:59:28
ふじさんありがとうございます。
>これ、flockを実装していない機械の場合、ロック機構が全く働かい
から(知らん顔して実行する)怖いですね(^^;
>自宅でWindows環境などでデバッグするための処置だとは思いますが。
>万が一NTがサーバの場合は気を付けないと。念の為。

次回の課題にさせてもらいます。
初心者の僕としてはFlockに関してまだ勉強不足でして、
単独テストを行う場合Errorになってしまうので、
eval'flock(LOG,2);';
ときべんさせています。が、とっても重要な事と把握し次回の課題にさせてもらいます。
ふじさんありがとうございました。

やす [E-Mail] 1999/06/28(月) 13:21:26
色々やって見ましたが限界です。
ヒントと言うよりも答えをもらっているような気がするんですがお手上げ状態です。
じぇいさん・・
お手数でなければ、僕のスクリプトを見て頂けると光栄なのですが。
(ちょっと人に見せるのは恥ずかしいのですが・・・)

じぇい 1999/06/28(月) 16:12:05
僕も経験浅なので、、あまり的確なことを教えられるかどうか、、。。

とりあえず、、スクリプトをテキスト形式にしてアップしてもらえますか?
、、で、、ちなみに、、何がお手上げなんでしょうか?
返信機能ですか?

じぇい [E-Mail] 1999/06/28(月) 16:13:58
ああ、、やはり、、メールで送ってもらえますでしょうか?

スクリプトの内容について、となると、、このラウンジを利用するのは、あまりよろしくないかと思うので。。

こちらもメールで返事を書きます。

やす [E-Mail] 1999/06/28(月) 16:26:25
じぇいさんREありがとうございます。
>、、で、、ちなみに、、何がお手上げなんでしょうか?
>返信機能ですか?
はい。
じぇいさんの削除機能を参考に返信機能へのカスタマイズがうまくいきません。
僕もはじめて書くスクリプトなので何かおかしな所があるのかと思われます。
大変ご迷惑おかけします。

やす 1999/06/29(火) 11:00:40
[[解決]]
解決!・・してもらいました。
これから復習に入るとこです。
exonさん ふじさん じぇいさん それと、この場所を貸してくださった"とほほ"さん、アリガトウございました。
じぇいさんには最後までお付き合い頂きありがとうございました。

[上に] [前に] [次に]