• ベストアンサー

データファイルからのデータの取得方法

 たびたびの質問ですみません。  初心者のため文法が理解できていないのか、今度はデータの読み込みでうまくいきません。  記述中のcgiファイルと同じディレクトリにdata.datというファイルがあり、そのファイルには三行のデータが記述されています。  内容は下記の内容です。 ---以下から--- 2006,03,18,,1800,グランド代,鈴木,公園,練習 2006,03,19,1500,,部費,加藤,#1鈴木,2006年度 2006,03,25,1500,,部費,加藤,#2太田,2006年度 ---以上まで---  このデータを各変数に割り当てたいのですが、うまくいきません。  下記のように記述していますが、いかがなモノでしょうか? ---以下から--- $fileline = 0; open FD, "<data.dat" || die $!; while (<FD>) { $fileline++; } close FD; open(FILE, "<data.dat") or printErrorPage("データファイルが開けません。"); eval{ flock(FILE, 1); }; @data = <FILE>; close FILE; for($k=0; $k<$fileline; ++$k){ ($year,$month,$date,$in,$out,$mono,$member,$etc1,$etc2) = split(/\,/, $data[$i]); $totalin = $totalin + $in[$k]; $totalout = $totalout + $out[$k]; } $totalinout = $totalin - $totalout; ---以上まで---  最終的に$totalinには1500と1500が足されて3000と入って、$totaloutには1800と入って、$totalinoutには3000から1800が引かれて1200と計算されるようにしたいのです。

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

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

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

直接的な原因は、 >split(/\,/, $data[$i]); で、未使用の変数 $i を使用しているためです。 --------------------------------------------------------------- open(FILE, "<:encoding(Shift_JIS)", "data.dat") or printErrorPage("データファイルが開けません。"); eval{ flock(FILE, 1); }; while(<FILE>){ ($year,$month,$date,$in,$out,$mono,$member,$etc1,$etc2) = split/,/; $totalin += $in; $totalout += $out; } close FILE; $totalinout = $totalin - $totalout;

mikami-no-hire
質問者

お礼

ありがとうございました。 記述までしていただき、大変参考になりました。

その他の回答 (1)

  • galluda
  • ベストアンサー率35% (440/1242)
回答No.1

がると申します。 んっと…あちこち突っ込みどころはあるのですが(苦笑 まず、最初の6行は不要に見えるのですが如何なものでしょう? ファイルの行数を取るだけなら、その後に出てくる@data配列の個数を調べれば等価だと思います。 もし「for文のため」であるならば、foreachというものを調べてみてください。多分「ああこんな便利なものが…」になると思うので。 後は、デバッグプリントを入れてみるとよろしいかと。 print文をあちこちに埋め込んで、そのときの変数の状態を調べます。 例えばfor文の直後に print $data[$i] . "\n"; とやれば、現在扱おうとしている文字列がはっきりしますし。 ちぃと大変かもしれませんが、頑張ってください。

mikami-no-hire
質問者

お礼

参考書を片手に、そして、他の方が作成したスクリプトを参考にしていました。 いわゆるデバッグプリントはやっているのですが、埋め込む場所がまるで意味がないところでした。 foreach、これから調べてみます。 ありがとうございました。

関連するQ&A

  • 低水準ファイル入出力

    openを用いてファイル:"test.dat"を開き、そのファイルにbuffに示すような適当なデータを書き込みたいのですが、 下記の様に記述してコンパイル、実行した結果"test.dat"内には何も記述されていませんでした。 自分でも調べてみたのですがどうしても上手くいかず、この場で質問させて頂きます。 ご指摘の程宜しくお願いします<(_ _)> #include <stdio.h> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> int main(void) {  char buff[]={"test123456789"};  int fd;  fd=open("test.dat",O_CREAT,S_IREAD|S_IWRITE);  if(fd==-1)   {    close(fd);    fd=open("test.dat",O_WRONLY);    if(fd == -1)    {      printf("open error <file>");      return 1;    }   }  write(fd,buff,sizeof(buff));  close(fd);  return 1; } ---- 私の環境 ---- Vine Linux 2.6r4

  • CSVデータの同じファイルに上書きするには。

    CSV形式でデータdata.csvが書いてあります。プログラムを実行して、そのファイルの$data[4]の値が5という数字だった場合は、そこのセルだけ"解除"という文字に置き換えて(ほかに入ってる値ははそのまま)data.csvに上書きしたいのですが、どうもうまくいきません。したのように記述したのですが、どこが間違っているのかがわかりません。。どなたか教えてください。よろしくおねがいします。 #!/usr/bin/perl $file='data.csv'; open(FILE, "$file"); while(<FILE>){ @data = split(/,/, $_); } close(FILE); if($data[4] eq "5"){$data[4] = "解除";} open(OUT, ">$file"); print OUT @data; close(OUT);

  • データからある文字列の次の行を出力するには

    perlの初心者です。はじめまして。 質問タイトルそのままなのですが、データからある文字列の次の行を出力するにはどのような記述をすればよろしいでしょうか?よろしくお願いします。 ・データは1ファイルで2000あります。1つのデータは[X,Y]で始まり、次の[X,Y]の前までになります。 ・出力はCSVファイル。 ・DAT errがあった場合はその次の行を出力。なかったら、DAT列は空白にする。 #!/bin/perl open(FILE,"<$ARGV[0]"); open(OUT,">$ARGV[0].csv"); ########################## err count ########################### print OUT "X,Y,NUMBER,DAT,\n"; while(<LOG>){ if($_ =~ /X=(.+)\,Y=(.+)/){ chomp($_); print OUT "\n$1,$2,"; } if($_ =~ /NUMBER (.+)/){ print OUT "$1,"; } if($_ =~ /DAT err/){ print OUT "PASS,0,"; } } close(OUT);

    • ベストアンサー
    • Perl
  • サーバに負担をかけずに複数のファイルを開きたいのですが

    複数のファイルを順番に開いていきたいのですが(その際、FLOCKを利用したいのですが)、サーバにかなりの負担がかかってしまうようです。負担がかからない方法などがありましたら、教えていただけると大変助かります。何卒よろしくお願いいたします。 具体的には、以下のように記述しているのですが、(素人の根拠のない思いつきで申し訳ありませんが)例えば、1行目の「for($k=1;$k<=15;$k++){」のあとに、「sleep」を入れると、少しは負担が軽くなるものでしょうか? もしも効果があるならば、何秒ぐらいが適当でしょうか? for($k=1;$k<=15;$k++){ #以下の作業を15回繰り返します $file="$k".".dat"; #ファイル名(1.dat~15.dat)指定 open(FILE, "$file"); #ファイルを開く eval{flock(FILE, 2)}; #ファイルロック $/ = ''; $tmp = <FILE>; #ファイル内データを$tmp入れる $/ = "\n"; close(FILE); #ファイルを閉じる } ちなみに、ファイルからデータを読み出すだけでなく、データを書き込むことも頻繁にあるため、ロックしている時間はできるだけ短くしたいと考えております。 何か良い方法がありましたら、教えていただけるとありがたいです。よろしくお願いいたします。

    • ベストアンサー
    • CGI
  • データファイルのソート方法について

    perlで使用している、データファイルのソート方法について質問いたします。 やりたいこと。 1.ファイルを読み込み 2.指定されている文字列でソートをして 3.同じファイルに格納する 以上になります。 以下のファイルにデーターが入ってます・ namedata.cgi 田中,4 佐藤,2 鈴木,1 水野,3 このファイルをソートして以下のように並び替えて保存したいと思ってます。 スクリプトを実行後 namedata.cgi 鈴木,1 佐藤,2 水野,3 田中,4 となっていてほしいのです。 スクリプト sort.cgi 略・・・ #ふぁいる読み込み open(DB,"<$file") || &error("Can't write $file"); flock(DB, 1); @lines = <DB>; close(DB); #ソート @result = sort { $a <=> $b } @lines; #ファイル書き込み open(DB,">$file") || &error("Can't write $file"); flock(DB, 2); print DB "@result"; close(DB); ファイルの2項目目が分からないからソートされていないような気がするのですが、記述方法がわかりません。 ファイル読み込み時にforeachを使用して読み込まないとだけなのでしょうか? うまく説明できていないかもしれませんが、よろしくお願いいたします。

    • ベストアンサー
    • Perl
  • ファイルの削除

    open(FH,">data.dat"); print FH "test"; close(FH); これが書いてあるCGIのページにアクセスすると、 自動的に「data.dat」というファイルが作成されますが、 ファイルを削除することは可能でしょうか? つまり、CGIのページにアクセスすると、「data.dat」 ファイルを削除するということです。 ご教授よろしくお願いします。

    • ベストアンサー
    • Perl
  • perlで容量の大きいCSVファイルを開く方法

    perlで容量の大きいCSVファイルを開く方法 ファイル容量の大きいcsvファイルから、必要な項目を抜き出して別ファイルにするプログラムを作成したいと思ってます。 csvファイルが少ない場合は動作したのですが、容量が140MBを超えたデータを読み込もうとすると、ブラウザー表示で何も変化いたしません プログラムは以下のようになってます。 ------------------------------------------------- 略 open(IN,"$inport") || &error(" $inport を読み込みopen出来ません"); flock(IN,1); @lines = <IN>; foreach $lines (@lines) { local(@val) = split("\,", $lines); print "$val[0]"; $dat .= "$val[1]\,$val[5]\n"; } open(OUT,">$dcsv"); flock(OUT,2); print OUT "$dat"; close OUT; 略 ------------------------------------------------- 件数も多いので、foreachを$lines (@lines) としないで($start .. $end)として読み込みの件数を制限して対応しようと考えてましたが、うまくいきませんでした。 ご指導いただけますと幸いです。

    • ベストアンサー
    • Perl
  • ファイルからランダムにデーターを取り出す方法。

    こんにちわ a.datと言うファイルの中に、1111(改行)2222(改行)3333(改行)と言うデータがあるとして そのデーターをランダムに取り出しだすプログラムはどのように記述すればいいでしょうか?

    • 締切済み
    • PHP
  • 全行読み込むには

    open( IN, "pass.dat" ) or die "Can't open pass.dat: $!"; $f_data = <IN>; close( IN ) or die "Can't close pass.dat: $!"; $f_data1 = $f_data; $f_data2 = $f_data; $f_data1 =~ s/<br>//g; $f_data2 =~ s/\S//g; open( OUT, ">log.dat" ) or die "Can't open log.dat: $!"; select OUT; print "$f_data1"; print "$f_data2"; select STDOUT; close( OUT ) or die "Can't close word.js: $!"; 上記スクリプトでは、pass.datの一行目しか読み込まれません。全行を読み込むためにはどのように書き換えればいいのでしょうか?宜しくお願いします。

    • ベストアンサー
    • Perl
  • Perlでファイル書き込みの際の不思議

    WEB上でPerlCGIを稼働し、ファイル(file.dat)からデータを読み込み、 @line=(0001,0002,0003) とします。 このときファイルの中身は 0001 0002 0003 という風に改行されています。 そして、@lineをいろいろ操作し、最終的に @newline=(0001,0003) とし、 (実際には各要素には改行がついています) これを open(OUT,">file.dat") print OUT @newline; close (OUT); と言う風に書き込み処理しました。 すると、ファイルの中身はなぜか 0001 0003 0001 0002 0003 もしくは 0001 0003 00001 0001 0002 0003 となってしまいます。(この違いはいろいろ試しているうちに発生しました) もちろん上書きオープンです。 試しに @newline を空にして書き込むとファイルは空になりました。 どう試してみても、新しいデータと古いデータが書き込まれてしまうのです。 場合によっては心当たりの無いデータまで・・・ 書き込みの前後で@newlineを画面表示してみましたが、 書き込みの前も後も問題なく表示されています。 つまり、書き込まれたデータだけが異常なのです。 今まで、データの更新→書き込み というのを いろいろやってきましたが、このような現象は初めてです。 原因として考えられることを教えてください。 よろしくお願いします。

    • ベストアンサー
    • CGI

専門家に質問してみよう