ログ先頭の一行読み出して文字を追加するには?

[上に] [前に] [次に]
/../ 1999/05/27(木) 21:43:36
本体のスクリプトに
<form action="./res.cgi" method=POST>
レス<input type=text name=res size=40>
<input type=submit value="返信する"></form>
というふうにフォームを作ってres.cgiを呼び出すようにしました。
res.cgiは、
#!/usr/bin/perl

require "./jcode.pl";
$datafile = './gb.dat'; #ログファイル

$res = $form{'res'};
&jcode'convert(*res,"sjis");
open(DATA,>$datafile);
$value = <DATA>;
chop;($no,$name,$msg,$mail,$url) = split(/,/, $value);

$msg = "$msg<br>$res"; #レスを追加
print "$no,$name,$msg,$mail,$url";
close(DATA);
exit;
と書いたのですが動いていないようなのです。記述間違っているんでしょうか?
最終的にはログの一行目を書き換える作業をして、
処理が終わると「書き込みありがとう」の一行を表示したいのです
よろしくお願いします。

B-Cus 1999/05/27(木) 21:59:04
> 動いていないようなのです。
動いてないとはどういう意味ですか? エラーになるんですか?
> $res = $form{'res'};
どこで$formに値を代入してるんですか?(省略しただけなら失礼)
> open(DATA,>$datafile);
ファイルに書き込みたいのですか?
というか、これってクォーティングしないと文法エラーになりませんか?
> chop;($no,$name,$msg,$mail,$url) = split(/,/, $value);
この chop、意図通りに動いてますか?

あと、Content-typeの出力は?(省略しただけなら失礼)

まず、手元にhttpdとperlを入れましょう。
いちいち人に聞いてると、開発効率上がらんでしょう。

/../ 1999/05/28(金) 03:23:18
お返事ありがとうございます。
このように↓書き直してみたのですが、
#!/usr/local/bin/perl

require "./cgi-lib.pl";
require "./jcode.pl";
&ReadParse;
$txtfile = './gb.dat';

$res = $in{"res"};
&jcode'convert(*res,"sjis");

open(OUT,">$txtfile");
$line = <OUT>;
($no,$name,$msg,$mail,$url) = split(/,/, $line);
$msg = "$msg<br>$res"; #レスを追加
print OUT "$no,$name,$msg,$mail,$url";
close(OUT);

print "Content-type: text/html\n\n";
print "<html><head><title>かきこみ完了</title></head>\n";
print "\n";
print "<h1>かきこみ完了</h1>\n";
exit;

「1,2,3,4,5」と書いたgb.datに「テスト」と編集してみたところ、
「,,3テスト,,」というふうに$msg以外は空の値が返ってきちゃいます。
ローカルで本と、にらめっこしながらやってるのですが
うまくいかないので教えてください。

じぇい 1999/05/28(金) 03:41:36
もとのスクリプトをテキスト形式にしてアップしてもらったほうが良さそうな気がします、、。
原因のわからないものはどこに原因があるかわかりませんから。

B-Cus 1999/05/28(金) 03:45:10
> open(OUT,">$txtfile");
> $line = <OUT>;
open(IN,"$txtfile");
$line = <IN>;
close(IN);

> print OUT "$no,$name,$msg,$mail,$url";
open(OUT,">$txtfile");
print OUT "$no,$name,$msg,$mail,$url";

…と思ったら、
> ,,3テスト,,
はて、3だけ読めてるのは何故?

なえ 1999/05/28(金) 08:32:24
>最終的にはログの一行目を書き換える作業をして
これって要するにファイルの途中にデータを挿入するってことになりますよね。
残念ながらそういうことはできません。(CPANを探せばそういうモジュールがあるかもしれないですけど)
ですのでファイルの中身を全て読み込んで、一行目の部分を書き換えて、全て書き出すということになります。


なえ 1999/05/28(金) 08:35:48
ちなみに
>open(OUT,">$txtfile");
この開き方だと、開いたときにファイルの中身全て消えます。
>,,3テスト,,」というふうに$msg以外は空の値が返ってきちゃいます。
なぜ3だけ読めてるんでしょ?多分バグ?ですね(^_^;

/../ 1999/05/28(金) 10:19:22
みなさんありがとうございます。
#!/usr/local/bin/perl

require "./cgi-lib.pl";
require "./jcode.pl";
&ReadParse;

$txtfile = './gb.dat';
$tempfile = "temp";
$res = $in{"res"};
&jcode'convert(*res,"sjis");

open(IN,"$txtfile");
$line = <IN>;
close(IN);

($no,$name,$msg,$mail,$url) = split(/,/, $line);
$msg = "$msg<br>$res"; #レスを追加

open(TMP,">$tempfile");
print TMP "$no,$name,$msg,$mail,$url";

open(DATA,$txtfile);
while (<DATA>) {
print TMP $_;
}
close(DATA);
close(TMP);
rename($tempfile,$txtfile);

print "Content-type: text/html\n\n";
print "<html><head><title>かきこみ完了</title></head>\n";
print "\n";
print "<h1>かきこみ完了</h1>\n";
exit;
一番上に編集した行を追加するように変更して、
これで完成だと思ったのですが、
これだと編集前の記事も残っちゃってて
返信するたびに編集前の記事が生まれてきます(;´Д`)

ログの先頭の一行を読み込んだあとに、その行を削除するような
処理はできるのでしょうか・・?

テストするときはフォーム部分のみを書いたHTMLと、
このres.cgiと、ログファイルのgb.datの3つだけで行っています。

いわた 1999/05/28(金) 10:43:57
>open(DATA,$txtfile);
>while (<DATA>) {
>print TMP $_;
>}
>close(DATA);
ここで編集前のものを書き込んでます。
これいらないんじゃないですか?

いわた 1999/05/28(金) 10:57:14
失礼。勘違いしていました。

>ログの先頭の一行を読み込んだあとに、その行を削除するような
>処理はできるのでしょうか・・?

open(DATA,$txtfile);
@hoge = <DATA>;
close(DATA);
for($i=1;$i<=$#hoge;$i++) {
  print TMP $hoge[$i];
}

というように$hoge[0]をよまないようにするとか?
ほかにもやり方はいろいろありますね。shiftとか。

あと、気になっているんですが、

>print TMP "$no,$name,$msg,$mail,$url";

は改行コードはいらないんでしょうか?


なえ 1999/05/28(金) 13:28:10
#!/usr/local/bin/perl

require "./cgi-lib.pl";
require "./jcode.pl";
&ReadParse;

$txtfile = './gb.dat';
$tempfile = "temp";
$res = $in{"res"};
&jcode'convert(*res,"sjis");

open(TMP, "+> $tempfile");
flock(TMP, 2);

open(IN, "$txtfile");
flock(IN, 1);

$line=<IN>;

($no,$name,$msg,$mail,$url) = split(/,/, $line);
$msg = "$msg<br>$res"; #レスを追加

print TMP join(",", ($no,$name,$msg,$mail,$url));

while ($line = <IN>){
    print TMP $line;
}

close(IN);

open(OUT, "> $txtfile);
flock(OUT, 2);

seek(TMP, 0, 0);

while ($line = <TMP>){
    print OUT $line;
}

close(OUT);

close(TMP);
open(IN, $txtfile);

print "Content-type: text/html\n\n";
print "<html><head><title>かきこみ完了</title></head>\n";
print "\n";
print "<h1>かきこみ完了</h1>\n";
exit;

こんな具合ですね。

なえ 1999/05/28(金) 13:42:29
ちょい修正。
#!/usr/local/bin/perl

require "./cgi-lib.pl";
require "./jcode.pl";
&ReadParse;

$txtfile = './gb.dat';
$tempfile = "temp";
$res = $in{"res"};
&jcode'convert(*res,"sjis");

open(TMP, "+< $tempfile"); # -- 修正 --
flock(TMP, 2);
truncate(TMP, 0); # -- 修正 --
seek(TMP, 0, 0); # -- 修正 --

open(IO, "+< $txtfile"); # -- 修正 --
flock(IO, 1); # -- 修正 --

$line=<IO>; # -- 修正 --

($no,$name,$msg,$mail,$url) = split(/,/, $line);
$msg = "$msg<br>$res";

print TMP join(",", ($no,$name,$msg,$mail,$url));

while ($line = <IO>){ # -- 修正 --
print TMP $line;
}

# close(IN); -- 削除 --

# open(OUT, "> $txtfile); -- 削除 --
# flock(OUT, 2); -- 削除 --

truncate(IO, 0); # -- 追加 --
seek(IO, 0, 0); # -- 追加 --
seek(TMP, 0, 0);

while ($line = <TMP>){
print IO $line; # -- 修正 --
}

close(IO); # -- 修正 --

close(TMP);
# open(IN, $txtfile); # -- 間違ってコピーしちゃった --

print "Content-type: text/html\n\n";
print "<html><head><title>かきこみ完了</title></head>\n";
print "\n";
print "<h1>かきこみ完了</h1>\n";
exit;

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