行数をカウントするプログラムで期待する結果が得られない

このQ&Aのポイント
  • 掲示板をperlで作るという課題に取り組んでいるが、行数をカウントするプログラムで期待する結果が得られない。
  • プログラムはPOSTされたコメントをdata.datに追記するもので、行数をコメントの先頭に表示する。
  • 試した結果、open(HOGE, ">> $myfile");やwhile(<HOGE>){$count = $count + 1;};の変更でも結果に変化はなかった。
回答を見る
  • ベストアンサー

while(<ハンドラ>) {} で行数をカウント

こんにちは。 掲示板をperlで作るという課題に取り組んでいるのですが、下記の部分の 動きだけがどうしても期待する動作がえられず、困っています。 なにか試した方が良い事がありましたら、ご指摘いただけないでしょうか。 プログラムの説明: POST されたコメントを data.dat に追記していくプログラムです。 ファイルハンドラから一行づつ読み込んで、行数を $count でカウントし、 『X行目&&コメント』のようにコメントの先頭に行数を表示します。 #!/usr/bin/perl $myfile = 'data.dat'; (省略) sub piyo{ open(HOGE, ">> $myfile"); flock(HOGE, 2); my $count = 1; while(<HOGE>){ $count++; }; print HOGE "$count行目&&in{'comment'}\n"; close(HOGE); }; data.dat の期待する結果は下記です。 1行目&&コメント 2行目&&コメント 3行目&&コメント ..... 実際に data.dat に書き込まれた結果は下記でした。 1行目&&コメント 1行目&&コメント 1行目&&コメント ..... 試した事1: open(HOGE, ">> $myfile"); を open(HOGE, "+>> $myfile"); した。 試した事2: while(<HOGE>){ $count = $count + 1; }; とした。 どちらでも結果に違いがありませんでした。 よろしくお願いします。

  • Perl
  • 回答数3
  • ありがとう数3

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

  • ベストアンサー
  • hirotn
  • ベストアンサー率59% (147/246)
回答No.2

+>>をご使用なので、ファイルハンドラが最後に移動してないでしょうか。 ハンドラが最後に移動しているので、whileは実行されておらず、常にファイル末尾に1行目が出力されるというシナリオを想像します。 Perlfaqを使用して… $lines = 0; $filename = "yahho.txt"; open(FILE, "+<$filename") or die "Can't open `$filename': $!"; #open に+<を使用 while (sysread FILE, $buffer, 4096) { $lines += ($buffer =~ tr/\n//); print "p"; } print FILE ++$lines . "やっほ~\n"; 注意 open時にファイルの存在は保証してください。存在しない場合エラーです。

jussmen_1979
質問者

お礼

hirotn 様 ご指摘のとおりでした。ありがとうございました。

その他の回答 (2)

  • hirotn
  • ベストアンサー率59% (147/246)
回答No.3

当該Perlfaqは以下のURLです。 http://perldoc.jp/docs/perl/5.14.1/perlfaq5.pod 「あるファイルの行数を数えるには」 が該当します。 数えた後はファイルハンドラは終端になっているのでご希望の処理を追加するようにしています。

jussmen_1979
質問者

お礼

こういったサイトをまず最初に確認すべきなのですね。 教えていただきありがとうございます、次回からまずは perldoc から情報を探してみます。

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

open(HOGE, ">> $myfile"); は「追加書き込み」モードでファイルを開きます。 while(<HOGE>){ で「読む」ことができるでしょうか?

jussmen_1979
質問者

お礼

kmee 様 ご返信ありがとうございます。 +>> でも試してみたところ意図通りに動かなかったのですが、 +> だと期待する動作が得られました。 細かな違いまで意識が及んでおらず、気がつけておりませんでした。 コメントありがとうございました。

関連するQ&A

  • textareaに入力されたデータを読み込む

    例えば以下のようにtextarea内にデータが入力されているとします(カンマ区切り,スペース区切り,タブ区切りなどはなんでも良いのですが)。 +---ここから---+ 1 2 3 4 5 6 7 8 9 10 11 12 +---ここまで---+ これらのデータを配列に格納する方法が,だいぶネットサーフィンしていたのですが分かりません。 以降,Perlになってしまうのですが,1行ずつ配列にdat=(1,2,3,4)のように格納していくか,あるいは行列(2次配列)の形で格納したいのです。 $pathname="D://datafile.dat"; open MYFILE, "$pathname"; while (<MYFILE>) { chomp; @{"dat$."} = split /,/; } close MYFILE; +----------- $pathname="D://datafile.dat"; open MYFILE, "$pathname"; @dat = map {chomp;[split /,/]} <MYFILE>; close MYFILE;

  • CSVファイルのデータの行数を取得したい

    こちらではいつもお世話になっています。Perlに関して、初心者ですが教えてください。 CSVファイルについて、データの存在する行数を取得したいと考えています。自分なりに考えたところでは、下記の方法で取得できるのではと思ったのですが・・・・・ open(FH,"data.csv"); @array = <FH>; $count = $#array; close(FH); data.csvは、1行目から順にデータが入っています。 これで、$countに1を足せばCSVデータの行数になるのではないかと考えています。 しかし、実際に動かしてみると、$countには、data.csvにデータがあるのに「-1」(要素なし)が返ってきます。何か間違いがあるのでしょうか。 あるいは、別にCSVデータの行数を取得する方法が他にあれば、教えていただけないでしょうか。 よろしくお願いします。

    • ベストアンサー
    • Perl
  • 読み込んだデータを配列へ代入する方法

    ---ここから--- 1,2 3,4 ---ここまで--- このようなファイルを読み込んでデータを配列へ格納するには, $pathname="D://data.txt"; open MYFILE, "$pathname"; @list=<MYFILE>; for($i=0;$i<2;$i++){ @dat=split(/,/,$list[$i]); print @dat; } close MYFILE; といったようなforあるいはwhileで1つの配列(上の場合だと@dat)に1行のデータを繰り返し入れていく方法しか思い浮かびません。できれば1行目のデータは@dat1という配列へ,2行目のデータは@dat2という配列へ,といったように行ごとに別々の配列へ代入させたいのですが良い方法はないでしょうか。 もしくは@dat=([1,2],[3,4])のような2次配列の形にでもできれば最高なのですが、、、

    • ベストアンサー
    • Perl
  • ファイルの中の行数を確認して、減らす

    今phpで掲示板を作っている初心者ですが、 ファイルの中の行数を確認してから、 ある一定数をオーバーしたら古いものからけしていく作業を したいのですが、上手く行きません。 ファイルの行数を確認する方法は、 $count=0; $fd=fopen("$filename","r"); while(!feof($fd)){ $data = fgets($fd); $count++; } な感じで、whileしか無理ですかね? この方法だとデータが多くなると心配です。 何かもっと良い方法はないでしょうか? また上で行数を調べて、例えば行数が100件を越したら一行消し、 それを再度ファイルに書き込むにはどうしたらよいのでしょうか? よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • エクセル、行数をカウントしたい。

    エクセル初心者です。 よろしくお願いいたします。 エクセルでこのような表を作っています。   A  B  C 1 10 15 2 20 3    10 4    15 5 10 6 10 10 7 8 この時、データの入っている行数をカウントしたいのです。 上の例では 「6」 です。 途中に空白の行はありません。 A列、B列にはどちらにも数字が入る場合と、どちらかにしか 入らない場合があります。 なので COUNT は使えないですよね? 今まではデータを入力後、下の空白の行を削除し、C列で COUNTBLANK として求めていたのですが、表の長さ(行数)が一定でないため、 体裁が悪くなってしまっていました。 希望としては。 最終行のC列に「終了」などと入れると、その文字列を判別 してくれて、それより上の行数をカウントしてくれる。 または 例えば OR を使って、A列B列どちらかにデータがある 場合のみ、カウントしてくれる。 こんなワガママなことができたら、と思っております。 補足が必要ならばいたします。 それと、遅くなるかもしれませんが、お礼は必ずさせていただきます。

  • mysqlの検索結果からある範囲の行数を取り出すには

    mysqlの検索結果からある範囲の行数を取り出すにはどうすればいいのでしょうか?たとえば検索結果から100~200行の間の行数を取り出すには、   ・   ・ $count=1; $result=mysql_query($sql); $rows=mysql_num_rows($result); while ($row=mysql_fetch_array($result)) { ・・・・ if( $count <= 99 ){ $count++; continue;} として99行目まで読み飛ばす処理をする以外に方法がありますか。 もっと効率よく取り出す方法があったら教えてください。

    • ベストアンサー
    • PHP
  • Cでファイルの行数をカウントするには

    ファイルの中の行数をカウントするにはどうすればよいか プログラムの行数ならその行数分だけ またコメントや空白行もカウントするにはどうしたらよいか 以下のプログラムに追加したい場合どうしたらよいか教えてください。 #include <stdio.h> int main(int argc , char *argv[]){ char s[256]; int i; FILE *fin; int local; int nCount = 0; for(i = 1 ; i < argc ; i++){ printf("%s\n",argv[i]); local = 0; fin=fopen(argv[i],"r"); memset(s,0,sizeof s); while(fgets(s,sizeof s,fin) != NULL){ // printf("%s",s); local++; nCount++; } memset(s,0,sizeof s); while(fgets) printf("local count = %d\n",local); fclose(fin); } printf("grobal count = %d\n",nCount); return 0; }

  • ファイルの読み込み時に場所を指定する

    #ファイルの読み込み $pathname="C://Perl/datafile/anovaCR.dat"; open MYFILE, "$pathname"; while (<MYFILE>) { chomp; @{"dat$."} = split /\t/; } $rows=$.; close MYFILE; といったように,コード中に既にデータが入力されたファイルを指定しているのですが,プログラムを実行した時に(Windowsなので)コマンドプロントの画面に 「ファイルの場所を指定してください。」 などと表示し,コマンドプロント上で C://Perl/datafile/anovaCR.dat と指定して読み込ませることは可能でしょうか。もちろん,可能は可能でしょうが「初心者には荷が重過ぎて無理」ではないかということです。手持ちの書籍には載っていませんし,webをどのように検索すればよいかもよく分かりません。

    • ベストアンサー
    • Perl
  • PerlでのCSV書き込みについて質問です。

    perl初心者です。 perlで投票のプログラミングを作ってるのですが、 どうもうまく動きません。 やりたいことは ・投票されたら  1)csvを読み込む  2)該当するNOのカウントをアップ  3)csvに書き込む という単純なことなのですが、 投票してもカウンタは0のままになってしまいます。 書き込み部分のプログラムが間違っているとは思うのですが 何が間違っているのかがどうしてもわかりません。 どなたかお知恵を貸してくださいm(__)m プログラムは下記のようになっています。 ================= foreach my $key (@key) { $val = $in{$key}; $in{$key} = &Jcode::convert(\$val, 'sjis'); } # データオープン open(DAT,"+< $datfile"); flock(DAT, 2); my @data; while (<DAT>) { push(@data,$_); if (eof) { last; } } # データ書き込み truncate(DAT, 0); seek(DAT, 0, 0); my $i=1 while (i<11){ my ($no,$name,$count) = split(/,/, $data[$i]); if($val eq $no){$count++;} if (eof) { last; } $i++; print DAT "$no,$name,$count,\n"; } close(DAT); ================= どうぞよろしくお願いします。

    • ベストアンサー
    • Perl
  • 複数ファイルで、それぞれの行数をカウントして出力する

    こんにちは。 お世話になります。 早速ですが、やりたい事は・・・ 複数のデータファイルを用意しています。 それぞれに異なるデータが入っています。 そして、そのファイル毎の行数を取得し、かつそれぞれにタイトルをつけたいのです。 例) 1.txtには10行分→出力する時には「帽子:10個」 data2.txt→8行→出力する時には「植木鉢:8個」 abc.txt→30行→→出力する時には「チョコレート:30個」 ・ ・ ・ そしてそれを改行しながら出力 例) 帽子:10個 植木鉢:8個 チョコレート:30個 ・ ・ ・ ひとつのファイルに対して行数を得るのは下記の通りできました。 $f_URL="1.txt";//ファイル指定 $line=file($f_URL);//配列に $gyosu=count($line);//要素数をカウント echo "帽子:$gyosu個";//出力 ひとつひとつやればできないこともないのですが、同じ処理をやるので何かまとめて処理できる方法があるんだろうなぁ・・・とは思ったのですが・・・行き詰まりました(汗) あとできればデータファイルの内容はいじらないように使いたいのです。(1.txtの1行目にタイトルをいれておく...などは避けたいのです) もし何かよい方法があればご教授&アドバイスよろしくお願い致します。

    • ベストアンサー
    • PHP

専門家に質問してみよう