ファイルに書き込めない/ファイルの内容が消える

このQ&Aのポイント
  • 編集機能を掲示板に追加した結果、テキストファイルの内容が消える問題が発生しています。
  • 原因は「重複があったら置き換えるルーチン」を追加したことにより、書き込みができなくなったことです。
  • 解決策として、pushではなくunshiftを使用することで書き込みができるようになる可能性があります。
回答を見る
  • ベストアンサー

ファイルに書き込めない/ファイルの内容が消える

編集機能を掲示板につけているところです。 テキストファイルの内容がまったく消えてしまうのです。 どうしてでしょうか? データ形式 314:2006年2月20日(月)22時31分:あああ:いいい:ううう 313:2006年2月20日(月)22時31分:あああ:いいい:ううう 312:2006年2月18日(土)23時18分:あああ:いいい:ううう #コード↓######################################## open(KEIJI, ">keijiban.dat") || die "File 'keijiban.dat' Open Error."; @all = <KEIJI>; $num = $all[0] + 1 if( $num eq '' ); $title = &henkan($form{'title'}); $topic = $form{'topic'}; $message = $form{'message'}; #***** 文字列の置換 ***** $message =~ s/\r\n/<BR>/g; # 日本語表記の日時を得るサブルーチン $time = &jp_time if( $time eq '' ); # 重複があったら置き換えるルーチン foreach(@all){ $data = $_; chop $data; ( $fnum ) = ( split(/:/,$data) )[0]; if ( $fnum == $num ) { $data = "$num:$time:$title:$topic:$message\r\n"; &jcode'convert(*data, 'sjis'); } push @all, $data; } die "File 'keijiban.dat' Open Error."; flock(KEIJI, 2); foreach (@all){ print KEIJI $_,"\n"; } flock(KEIJI, 8); close(KEIJI); ~~~~~~~~~~~~~~~~~~~~~~~~ どんどん手をつけていったら書きこめなくなってしまいました。最初は書き込めていたんですけど・・・。 真ん中あたりのじ「重複があったらおきかえるルーチン」を付け加えていたら書き込めなくなりました。書き込めたときはpushではなくunshiftを使っていました。

noname#102630
noname#102630
  • Perl
  • 回答数1
  • ありがとう数1

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

  • ベストアンサー
  • moon_night
  • ベストアンサー率32% (598/1831)
回答No.1

open(KEIJI, ">keijiban.dat") || die "File 'keijiban.dat' Open Error."; として、ファイルを開いた時点で中身が消えます。 open(KEIJI,"<keijiban.dat") として開いて、データを読み込んだ後に処理をしましょう。

noname#102630
質問者

お礼

回答ありがとうございました。 そのへんを変えてみたところ内部エラーが出てしまいました。 これで書き込みモードとかのopen方法はあっていると思うのですが、どこがおかしいのかわかりません。 図ずうしいですが、もしわかったら教えてください。 open(KEIJI, "keijiban.dat") || die "File 'keijiban.dat' Open Error."; # 過去のデータを全て配列に読み込む @all = <KEIJI>; # HTMLタグと衝突する記号などを変換 $num = $all[0] + 1 if( $num eq '' ); $title = &henkan($form{'title'}); $topic = $form{'topic'}; $message = $form{'message'}; #***** 文字列の置換 ***** $message =~ s/\r\n/<BR>/g; # 日本語表記の日時を得るサブルーチン $time = &jp_time if( $time eq '' ); # データを1行にまとめる(項目の区切りはコロン) foreach(@all){ $data = $_; chop $data; ( $fnum ) = ( split(/:/,$data) )[0]; if ( $fnum == $num ) { $data = "$num:$time:$title:$topic:$message\r\n"; &jcode'convert(*data, 'sjis'); } push @all, $data; } close(KEIJI); open(KEIJI, ">keijiban.dat") || die "File 'keijiban.dat' Open Error."; flock(KEIJI, 2); # (新規データ+過去データ)をファイルに上書き   print KEIJI @all; flock(KEIJI, 8); close(KEIJI);

noname#102630
質問者

補足

ちなみに最初のOPENとCLOSEで間違っていることはわかりました。この開き方ではどうしてだめなんでしょうか?

関連するQ&A

  • 新しい書き込みができない、編集は可能。

    たびたび失礼します。 編集機能のついた掲示板を作成中です。 編集機能はつけられたのですが、今度は新しい書き込みができなくなりました。 新しい書き込みをすると、新しいデータが保存されずデータが逆に保存されたり、消えたりします。 ソース↓ open(KEIJI, "keijiban.dat") || die "File 'keijiban.dat' Open Error."; # 過去のデータを全て配列に読み込む @all = <KEIJI>; # HTMLタグと衝突する記号などを変換 $num = $all[0] + 1 if( $num eq '' ); $title = &henkan($form{'title'}); $topic = $form{'topic'}; $message = $form{'message'}; foreach(@all){ $data = $_;     $count = 0; ( $fnum ) = ( split(/:/,$data) )[0]; if ( $fnum == $num ) { $data = "$num:$time:$title:$topic:$message\r\n"; &jcode'convert(*data, 'sjis'); $count++; } if( $count == 0 ){ unshift @all_data, $data; } else { push @all_data, $data; } } ################################################ $countで新しいデータか編集かを分岐させたつもりなのですが、ここの処理が上手くいっていないようです。 怪しいのは、 unshift、$dataにちゃんとデータが入っているか、というところが怪しいように感じました。 もしヒントがあれば教えてください。 よろしくお願いします。

    • ベストアンサー
    • Perl
  • 【再】Cookieを使用してフォームで送信

    #!/usr/local/bin/perl # ライブラリ require 'cgi-lib.pl'; require 'jcode.pl'; require 'keiji_write_sub.pl'; # デコード &ReadParse(*form); # 名前・メッセージ欄のチェック if ($form{'name'} eq "" || $form{'message'} eq "") { # 名前・メッセージが空ならエラー &input_error; # 終了 exit; } else { # 名前・メッセージも空でないなら書込処理 # HTMLタグと衝突する記号を変換 $name = &henkan($form{'name'}); $mail = &henkan($form{'mail'}); $title = &henkan($form{'title'}); $message = &henkan($form{'message'}); $message =~ s/\r\n/<BR>/g; # 日本語表記の日時を得る $time = &jp_time; # データを1行に(区切りはコロン) $new_data = "$time:$name:$mail:$title:$message\n"; &jcode'convert(*new_data, 'sjis'); open(KEIJI, "<keijiban.dat") || die "File 'keijiban.dat' Open Error."; # 過去のデータを全て配列に読み込む @all_data = <KEIJI>; close(KEIJI); # 配列の先頭に新規データ追加 unshift(@all_data, $new_data); open(KEIJI, ">keijiban.dat") || die "File 'keijiban.dat' Open Error."; #flock(KEIJI, 2); # (新規データ+過去データ)をファイルに上書き print KEIJI @all_data; #flock(KEIJI, 8); close(KEIJI); # 書込完了メッセ &write_ok; } というコードでdatファイルに書き込みしています。 この時に、名前などを1度入力したらCookieに記憶させて次からは自動で入るようにしたいのです。 あちこち検索して読んだりしたのですが、わからなくて…。 どなたか教えてください。

    • ベストアンサー
    • CGI
  • 単純なお問い合わせフォーム

    お問い合わせのフォームを作り、確認、最後にメールを飛ばす仕組みを作っているのですが、メールにインプットされたデータが入ってこない状態で届きます。どうか助けてください。(息切れ) *下記参照 #フォームの情報を初めに格納する所 省略 #-------------------------------↓ if ( $ACT eq 'ckt' ){ &kakunin; } elsif ( $ACT eq 'ckt2' ) { open (KEIJI, "<keijiban.dat") || die "File 'keijiban.dat' Open Error."; # ファイルの内容を1行単位ですべて配列allに読み込む @all = <KEIJI>; # すべてのデータについて繰り返す foreach (@all){ # 1行の文字列をコロンを目印にして項目に分割する ($firstname) = split(/:/, $_); # 1件分のデータを表示するサブルーチン &sendmail; } close(KEIJI); #------------------------------------↑ sub kakunin{ $new_data = "$firstname\n"; &jcode'convert(*new_data, 'sjis'); open(KEIJI, "<keijiban.dat") || die "File 'keijiban.dat' Open Error."; # 過去のデータを全て配列に読み込む @all_data = <KEIJI>; close(KEIJI); # 配列の先頭に新規データを追加 unshift(@all_data, $new_data); open(KEIJI, ">keijiban.dat") || die "File 'keijiban.dat' Open Error."; #flock(KEIJI, 2); # (新規データ+過去データ)をファイルに上書き print KEIJI @all_data; #flock(KEIJI, 8); close(KEIJI); # 書きこみ完了メッセージ &write_ok; exit; } sub sendmail { #以下省略メール送信プログラム exit; }

    • 締切済み
    • CGI
  • 同じ文なのにちがうように表示される

    いま掲示板に編集機能をつけているのですが、テキストファイルに編集したあとのファイルを読み込んでHTMLとして出力すると変な風に出力されます。 そしてまたバックアップしておいた外見同じのテキストファイルをアップして表示すると正しく表示されます。 見た目同じ文で違うように出力されるということは16進数やsjisなどのせいでしょうか? テキストファイル↓ 325:2006年9月1日(金)21時41分:遊び:広告:わーい 324:2006年9月1日(金)20時41分:遊び:広告:あああ 読み込むソース↓~抜粋 open (KEIJI, "<keijiban.dat") || die "File 'keijiban.dat' Open Error."; # ファイルの内容を1行単位ですべて配列allに読み込む @all = <KEIJI>; #↓ページ制御の文があるが抜粋 print << "END"; <TABLE WIDTH="500" BORDER=0 CELLPADDING="2"> END # すべてのデータについて繰り返す foreach (@all[ $page_start_line..$page_end_line]){ # 1行の文字列をコロンを目印にして項目に分割する ($num, $time, $title, $topic, $message) = split(/:/, $_); # 1件分のデータを表示するサブルーチン &contents; } sub contents { print << "END_OF_ONE"; <TR> <TD> <font size="2">$time  </TD><TD><A HREF="$self?view_page=$num"><B>$title</B></A></TD> <TD>$topic</font></TD> </TD> </TR> END_OF_ONE } 書き込みソースも補足した方がよろしいでしょうか? 書き込み(編集)の段階でまちがっているのか、読み込みの段階でまちがっているのかわかりません。 これだけでは情報不足とは思いますが、心当たりがあるようでしたらヒントをおあたえください。

    • ベストアンサー
    • Perl
  • sendmailができない

    (1)お問い合わせフォームを入力(2)入力データを確認する(3)最後に指定先のメールに送り終了 という具合ですが(3)のところで指定先にメールが届きません。メール自体も送られてこないのですがどのような方法があるのでしょうか?どうか教えていただけないでしょうか?お願いします。 (3)のソースコートです。------------- &header; open (KEIJI, "<keijiban.dat") || die "File 'keijiban.dat' Open Error."; # ファイルの内容を1行単位ですべて配列allに読み込む @all = <KEIJI>; split(/:/, $_); if( $_ = $all[0] ){ ($time, $name, $mail, $title, $message, $to) = split(/:/); #送信前処理 &jcode'convert(*subject,'jis'); &jcode'convert(*body,'jis'); # send mail open(MAIL, "| /usr/lib/sendmail -t"); print MAIL "TO: $to\n"; print MAIL "From: $from\n"; print MAIL "Subject: $subject\n"; print MAIL "Content-Type: text/plain;\n\n"; print MAIL "\n"; print MAIL "---------------------------------------------\n"; print MAIL " 名前:$name\n"; print MAIL " 内容:$body\n"; print MAIL " お名前:$firstname $secondname\n"; print MAIL " かな:$kanafirstname $kanasecondname\n"; print MAIL " 所在都道府県 :$area1 $area2\n"; print MAIL " 電話番号:$telno\n"; print MAIL " 性別:$sex\n"; print MAIL " メールアドレス:mailto:$mailad\n"; print MAIL "お問合わ、ご相談内容:"; print MAIL " $con1\n"; print MAIL "---------------------------------------------\n"; close(MAIL); &one_message; } close(KEIJI); # フッターを表示するサブルーチン &footer;

  • 投稿内容が文字化けして記録されてしまう。

    #!C:/Perl/bin/perl require 'cgi-lib.pl'; &ReadParse(*answer); $data="$answer{'name'}\n$answer{'mail'}\n$answer{'sex'}\n$answer{'how'}\n$answer{'corner'}\n$answer{'kansou'}\n\n\n\n"; require 'jcode.pl'; &jcode'convert(*data,'euc'); ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time()); $mon=$mon+1; @youbi=('日','月','火','水','木','金','土',); $time="$mon月mday日youbi[$wday]曜日hour時$min分$sec秒$\n"; open(ANSWER,">>answer.dat"); flock(ANSWER,2); print ANSWER"$time$data"; flock(ANSWER,8); close(ANSWER); print"Content-type:text/html\n\n"; print<<EOF; <html> <head> <title>ありがとうございました</title> </head> <body> <center> <font size="2"> <coloe="black"> ご協力ありがとうございました<br><br><br> </font> </center> </body> </html> EOF exit; -------- 課題をだされたので、以上のような内容の アンケートフォームを作りました(作ったというか テキストをほとんど写しただけですが) 使用エディタは秀丸です。 実際、これをform.htmlから動かすと、answer.datに 記録される内容が文字化けしてしまい、読めないの です。 テキスト通りにやったつもりですが、「文字コードを EUCで保存」とあったのですが、EUCで保存すると 上述したスクリプトの日本語が文字化けしてしまう ため、そのまま(shift-jis)で保存しています。 課題が出せないと困るので、どうすれば記入した ものが文字化けせずに出力されるか教えていただけ ないでしょうか?

    • ベストアンサー
    • CGI
  • mkdirでのファイルロック

    私はCGIの経験がほとんどなく超初心者です。下記のようなファイルを作りましたがファイルのロックをしなければデータが書き込まれないようなので困ってしまっています。flockはつかえないようなのでmkdirでロックをかけたいのです。 #! /usr/local/bin/perl $| = 1; require './jcode.pl'; require './mimew.pl'; require './cgi-lib.pl'; &ReadParse(*FORM); $thisfile = 'mother'; $countfile = './mother.txt'; $predatadir ='./mom'; $fromname = "sabra net"; $fromemail = '***@****.co.jp'; $act = $FORM{'act'}; #### main始動 #### if($act eq "indata"){   &getnumber;   &datamod;   &inputDB;   &mailsend;   &view; } else{   &datamod;   &kakunin; } #### main終了 #### #### メッセージ番号設定 #### sub getnumber {   open(COUNTER,"$countfile") || &error('countfileが開けない');     $this_num = <COUNTER>;   close(COUNTER);     $this_num++;   open(COUNTER,">$countfile") || &error('countfileに書きこめない');     print COUNTER "$this_num";   close(COUNTER);   if( length($this_num) == 1 ){     $this_num ="000000" . $this_num;   }   elsif( length($this_num) == 2 ){     $this_num ="00000" . $this_num;   } } #### datafileへ入力 #### sub inputDB {   $datafile = "$predatadir/userdata01.csv";    open(DB,">>$datafile") || &error('datafileに書きこめない');      print DB "$yourname,$email\n";    close(DB); }

    • 締切済み
    • CGI
  • perlで作った掲示板、エラーが出てしまう。

    課題でperlの掲示板を作成したのですが、動作せず困っています。間違いを教えてください。 #!C:/Perl/bin/perl require 'html_data.pl'; require 'cgi-lib.pl'; require 'jcode.pl' if($ENV{'REQUEST_METHOD'}eq"POST"){ &ReadParse(*answer); $name=$answer{'name'}; $mail=$answer{'mail'}; $title=$answer{'title'}; $text=$answer{'text'}; $name=~s/,/,/g; $name=~s/&/&/g; &name=~s/"/"/g; $name=~s/<</g; $name=~s/>/>/g; $mail=~s/,/,/g; $mail=~s/&/&/g; &mail=~s/"/"/g; $mail=~s/<</g; $mail=~s/>/>/g; $title=~s/,/,/g; $title=~s/&/&/g; &title=~s/"/"/g; $title=~s/<</g; $title=~s/>/>/g; $text=~s/,/,/g; $text=~s/&/&/g; &text=~s/"/"/g; $text=~s/<</g; $text=~s/>/>/g; $data="$name,$mail,$title,$text"; &jcode'convert(*data,'sjis'); if($name ne""&& $title ne""&& $text ne""){ ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time()); $mon=$mon+1; @youbi=('日','月','火','水','木','金','土'); $time="$mon月$mday日$youbi[$wday]曜日$hour時$min分"; $all_data="$time,$data\n"; open(ANSWER,"<answer.dat"); @all=<ANSWER>; close(ANSWER); unshift(@all,$all_data); open(ANSWER,">answer.dat"); flock(ANSWER,2); print ANSWER @all; flock(ANSWER,8) close(ANSWER); } } &form; open(ANSWER,"<answer.dat"); @all=<ANSWER>; foreach(@all){ ($time,$name,$mail,$title,$text)=split(/,/,$_); &toukou; } close(ANSWER); &footer; exit;

    • ベストアンサー
    • Perl
  • 行頭に変なスペースが…

    入力したデータをログファイルの一番上に入れたいために以下のようにしました。 open(FH2,"***.log"); flock(FH2,2); @files = <FH2>; flock(FH2,8); close FH2; open(FH,">***.log"); @filew = "user=$FORM{'name'}<>TIME=$FORM{'TIME'}\n@files"; print FH @filew; close(FH); こうするとなぜかログファイルの2行目以降の頭にスペースが1文字分入ります。 2個目のログファイルオープンの3行目 print FH @filew; のスペースが原因かと思い、 print FH@filew; としてみましたが、やっぱりスペースが入りました。 このスペースを入らないようにするにはどうしたらいいでしょうか?

    • ベストアンサー
    • Perl
  • ファイルの上書き

    初心者です。 ファイル(count.dat)にデータのカウント数を上書きしていきたいのですが、実行しますとファイルが壊れてしまいどこで失敗しているのか分かりません。。 以下のように記述したのですが、アドバイス頂けないでしょうか。 ちなみにcount.datの中身は以下の通りです。 0,0 1,0 2,0 3,0 4,0 5,0 6,0 $max_numの値が別に算出されており、$max_numが1だったら上記の1,0を1,1に、$max_numが2だったら上記の2,0を2,1に上書きしたいと思っています。$max_numでない部分(3,0や4,0や5,0)はそのまま変更なしで保存させたいです。 #ファイルの読み込み $num=0;#過去の人数 $qNo=0;#Qナンバー $l=0; open openDat,'<count.dat' or die "file not Exist!!"; while (<openDat>){ $a[l]=$_; $qNo=substr($a,0,1); if($max_num=$qNo){       $num[l]=substr($a[l],2); $num[l]+=1; $a[l]="$qNo".","."$num[l]"; print $a[l]; }else{ $num[l]=substr($a[l],2); } $l+=1; } close openDat; open openDat,'>count.dat' or die "file not Exist!!"; for( $j=0; $j<=6; $j++) { print openDat $l,"\n"; } close openDat;

    • ベストアンサー
    • Perl