こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

CSVデータ修正時のファイルへの書き込み不具合?

こんにちは。
初心者ながら、PerlでCSVファイルを使って簡易的なDBを作っています
その際、下記の方法でCSVファイルの修正していますが、うまくいきません><
申し訳ありませんが、お知恵をお借りできますでしょうか?
困っております(泣)

◆下記プログラム内容
 CSVを読み込み、一致する部分があればそこを修正し、新たなCSVとして書き出す

◆マスターDB(カンマ区切りのCSVファイルにて作成)
 ・DBは横230×縦max2000程度(現行は横200×縦100程度)
 ・先頭、横20までは日本語で、最大でも全角50文字程度(改行、カンマは事前に除外(置き換え)しています)
 ・その後は「1 or 空白」。(フラグが立っているか、いないかだけ)

◆発生する不具合?
 (1)修正箇所の後ろの2~3行が、修正行の後ろにそのまま追加される(欠落する場合もあり)
 (2)DBの一番最後の最後の行に不明なデータが追加される
  例1:,,,,,1,,,,,,,,1,,,,,,,,1,,,,,,,,1,,,,,,,,1
  例2:,,,,
  例3:改行のみ
 (3)上記、(1),(2)は基本的に同時発生
 (4)上記、(1),(2)が毎回ではなく時々発生(と言うか、かなり頻繁に… 10回に8回程…)

***************************************

# @master:CSVデータを読み込んだDB
# @data:修正内容の入っている配列
# @write_db:修正後の@master(これが新しいCSVとして書き込まれる)


#読み込み、及び修正
open (write_db,"+<db.csv");
flock write_db,2;
$i=0;
while(<write_db>){
@master = split(/,/, $_);
if( $master[0] == $data[0] )
{
$master[1] = $FORM{'textfield62'};
$master[2] = $FORM{'textfield6'};
$master[9] = $data[3];
$master[10] = $data[4];
$master[11] = $data[5];
$master[12] = $data[6];
$master[13] = $data[7];
$master[14] = $FORM{'textfield7'};
$master[15] = $FORM{'textfield5'};

#修正前の”1”のフラグ情報をクリア
for( $m = 21 ; $m <= $#master ; $m++ ){
$master[$m]="";
}

#修正情報の入っている@dataに基づいて@masterを変更(新しいフラグを立てる)
for( $k = 8 ; $k < $end_num ; $k++ ){
$master[$data[$k]] = 1;
}
}
$write_data[$i] = join(',',@master);
$i++;
}
seek write_db,0,0;
close (write_db);

#書き出し操作
open (OUT,"+<db.csv");
flock OUT,2;
foreach my $ii ( @write_data ){
print OUT $write_data[$ii];
}
seek OUT,0,0;
close (OUT);

投稿日時 - 2009-09-19 18:13:07

QNo.5303023

困ってます

このQ&Aは役に立ちましたか?

2人が「このQ&Aが役に立った」と投票しています

回答(1)

ANo.1

少なくとも 書き出し操作の
> foreach my $ii ( @write_data ){
> print OUT $write_data[$ii];
> }
の print は、
print OUT $ii;
の間違いですね。

その他、元の CSV にある改行コードは、書き換えでなくなって
いるかも。

投稿日時 - 2009-09-20 12:27:53

お礼

ご返答ありがとうございます!
>元の CSV にある改行コードは、書き換えでなくなっているかも
この点、修正させて頂き、不具合の(1)が解決いたしました!
(配列の最後の値にjoinで"\n"を付与致しました)

また、不具合の(2)~(4)については
最後の書き込み操作を下記の通り修正した所、解決致しました。
(seekをprintの前に持ってきて、その前にtruncateを付けました)
open (OUT,"+<db.csv");
flock OUT,2;
truncate(OUT, 0);
seek OUT,0,0;
foreach my $ii ( @write_data ){
print OUT $ii;
}
close (OUT);

まだまだPerl初心者ですが、t-okura様の助言もあり、少しづつ前に進んでおります!(と、思っておりますがw)
また不明な点あれば、ご相談させて頂く事あるかと思いますが、
何卒よろしくお願い致します。

本当にありがとう御座いました。

投稿日時 - 2009-09-24 17:14:42

あなたにオススメの質問