• ベストアンサー

fopenの"r+"モードで同時に読み書きする

カンマ区切りで一行に10個のデータ(data[0]からdata[9]とする)が入っているtxtファイルがあるとします。data[]はlong型とします。 ファイルを"r+"モードで読み込み、各行で、data[0]の値によって異なる計算を行い、その結果をdata[9]の値に加えたいとおもいます。 恐らく非常に基本的なことで、申し訳ないのですが、教えていただけると助かります。。 FILE *fp; fp=fopen(fp,"test.txt","r+"); for(int i=1;i<=rowcount;i++){ //ここでdata[0]からdata[9]を読み込んだとする // data[9]+=data[0]*2;//こういう処理をする /*そして、新しいdata[9]の値をもとのdata[9]の値と置き換えたい*/ } fclose(fp);

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

  • ベストアンサー
  • mac_res
  • ベストアンサー率36% (568/1571)
回答No.3

> 将来的に速度低下の原因にならないか、と危惧しまして、 text fileを使う限り基本的にその心配は無用です。 固定長にして、"r+"を使う手もありますが、高水準file I/Oにおいてはバッファリングの問題があり、出力入力の切替時はfflush(3)する必要があります。これによってバッファリングは無効となります。 これに対し、2個の入力用、出力用ファイルを開いた場合は、両方ともバッファリングが有効に作用するため、かえってI/Oに要する時間は短くなります。 速度が絶対的な場合、データーにtextを使うこと自体を見直すべきです。入出力変換は「高価」な処理です。 binary fileで、固定長の低水準I/Oを使ったプログラミングとなります。可読性も、データーの保守性も低下しますので、そこまでするかどうかは十分考慮すべきです。

すると、全ての回答が全文表示されます。

その他の回答 (2)

  • mac_res
  • ベストアンサー率36% (568/1571)
回答No.2

ご質問のように計算途中で、ファイル長が変化するような処理を"r+"で開いて1ファイルだけで処理するのは適当ではありません。 素直にtmpファイルを開いて計算結果を順次別ファイルに書き込み、全ての計算が終わってから、元ファイルを消して、tmpファイルをrenameすべきです。

kyotowim
質問者

お礼

とりあえずそのようにコーディングしたのですが、将来的に速度低下の原因にならないか、と危惧しまして、"r+"ではできないものか、という素人考えでした。 ありがとうございました。

すると、全ての回答が全文表示されます。
  • galluda
  • ベストアンサー率35% (440/1242)
回答No.1

がると申します。 まずは基礎概論から。 本を読むときに途中までとか読むと、しおりを挟みますよね? これと同じように、ファイルをopenすると、「ファイルポインタ」という名前のしおりが作成されます。 open直後は先頭に。そうしてread処理をすると「読んだところまで」ファイルポインタが進みます。 一つは「一度closeしてopenしなおす」とファイルポインタは先頭に戻るのですが。 もう一つ、直接ファイルポインタを操作する関数があります。 fopenを使われているのでしたら、fseekというのがそれにあたります。 Googleあたりでfseekで検索すれば色々と出てくるかと思います。 ちなみに、今回は「ファイルサイズが必ず同じか増えるか」なので不要なのですが、もしファイルサイズが減る可能性がある場合はtruncate(ftruncate)という関数を併用して、サイズを切り詰める必要があります。 以上、簡単ですが。

参考URL:
http://www9.plala.or.jp/sgwr-t/lib/fseek.html,http://www.linux.or.jp/JM/html/LDP_man-pages/man2/truncate.2.html
kyotowim
質問者

お礼

どうもありがとうございました。 truncateというのは初めて見ました。参考になりました。

すると、全ての回答が全文表示されます。

関連するQ&A