• ベストアンサー

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

  • fopenの追記モードについて

    宜しくお願いします。 fopenで追記モードでファイルを追記するとき、 FILE *fp; fp = fopen("hogehoge.txt", "a"); fprintf(fp, "aaa\n"); fclose(fp); fopen("hogehoge.txt", "a"); fprintf(fp, "bbb\n"); fclose(fp); と毎回ファイルを開きなおすと、出力結果が bbb aaa となってしまうのですが、 aaa bbb と出来ない物でしょうか?

  • 同時にファイル読み込み 書き込み

    現在、ヒストグラムのプログラムを作成しています。 まず0~255の1000個の乱数ファイルdata.txtを読み込み、 ヒストグラムは出来たのですが、 エクセルでグラフを作りたいので、 data1.txtに書き込みたいので、下のソースでやってみましたが、 0~255のカウントが全部0になってしまします。 fp = fopen("data1.txt","w");が無ければ正常に処理されます。 どうか教えてください。よろしくお願いします。 #include <stdio.h> #define BUF 10 #define MAX 256 void count(FILE *fp , int* counter); int main(void) { FILE *fp; fp = fopen("data.txt","r"); fp = fopen("data1.txt","w"); int counter[MAX]; int i; for(i=0 ; i<MAX ; i++) { counter[i] = 0; } count(fp , counter); for(i=0 ; i<MAX ; i++) { printf("%d %d\n" , i, counter[i]); } fclose(fp); return 0; } void count(FILE* p_file , int* counter) { char buf[BUF]; while (fgets(buf , BUF , p_file) != NULL) { int n; sscanf(buf , "%d" , &n); counter[n]++; } }

  • ファイルの読み書き

    ファイルに文字列を追加したいのですがファイルの開き方が "a" モードで開くと当然文章の最後に文字列が書き込まれることになります。 ですが、最後ではなく最初に文字列を追加したいためにファイルを2回づつ読み込んだり書いたりしたら2回目の読み込み時にバグが出ました どうしたらファイルの文字列を最後ではなく最初に追加できますか? 追加したい文字が: もも 今までのデーターが オレンジ みかん なら、 もも オレンジ みかん のようにしたい。 以下ソース ---ソース--- #include <stdio.h> void main(void){ FILE *fp; char *tm[1000]; char buf[400]; int i=1,sei; fp= fopen("now.txt","w+"); fprintf(fp,"もも"); fclose(fp); //何で最初に書き込んでるんだ? //という突っ込みがあるでしょうが本当に作りたいプログラムは最初にファイルに書き込まないといけないためです。 fp= fopen("now.txt","r"); while( fgets( buf, 400, fp ) != NULL ){ tm[0]=buf; } fclose(fp); printf("%s<br>",tm[0]); //確認用 この時点ではtm[0]に"もも"が入っている fp =fopen("moto.txt","r"); while( fgets( buf, 400, fp ) != NULL ){ tm[i]=buf; printf("%s<br>",tm[i]); //確認 この時点ではtm[1]に"オレンジ" tm[2]にみかんが入っている i++; } printf("%s<br>",tm[0]); //確認用 バグったtm[2]のみかんが入っている printf("%s<br>",tm[1]); //確認用 バグったtm[2]のみかんが入っている printf("%s<br>",tm[2]); //確認用 バグじゃない? fclose(fp); if(i<=1000){ sei=i; } else{ sei=1000; } fp =fopen("chat_deta.txt","w+"); for(i=0;i<sei;i++){ fprintf(fp,"%s\n",tm[i]); //バグった内容が書き込まれるためみかんが3列かきこまれる } fclose(fp); } } ---now.txt--- もも ---moto.txt--- オレンジ みかん 結果として みかん みかん みかん っとなっていますね。

  • fopenのモード文字列について

    fopenのモード文字列が w の時について何ですが、 #include <stdio.h> int main(void){ FILE *fp; fp=fopen("test.txt","w"); fclose(fp); return 0; } でファイルを作成した時 作成したファイルと同じディレクトリーに同じ名前のファイルが 存在するときは元のファイルに上書き(?)してファイルが作成されますよね? これは1度元のファイルを削除してから新たにファイルを作成しているのか、それとも元ファイルを空にしただけなのでしょうか?

  • fopenについて

    ご質問させて頂きます。 ファイルの中身は以下の通りです。 TX55123455846521113456211415122335122200452125442[EOF] という感じの 一行だけの細長いデータです。 このファイルのデータを 読み取ろうとして 以下の様にしました。 int main(void){ char buf[5]; FILE *fp; fp = fopen("ex.fil","r"); if (fp == NULL){ printf("can't open"); exit(1); } エラーは出ないのですが データがないと判断されてしまうようで 「can't open」 となってしまいます。 どういう点がおかしいのか お気づきな点がありましたら ご教示して頂けたら幸いです。

  • fopen関数について

    ----------------------------------------- #include<stdio.h> #include<stdlib.h> int main() { FILE *fp; char filename[80],ss[256]; printf("ファイル名="); gets(filename); if((fp=fopen(filename,"r"))==NULL){ printf("ファイルをオープンできません.\n"); exit(1); } while(fgets(ss,256,fp)!=NULL){ printf("%s",ss); } puts(""); fclose(fp); return 0; } ----------------------------------------- 初心者な内容の質問ですいません。 以上のプログラムでまず、「gets(filename);」により、「filename[80]」の配列に「aaa.txt」という文字列を格納し、そのファイルをfopenで読もう込もうとしています。 そこで、 if((fp=fopen(filename,"r"))==NULL) の部分に疑問があるのですが、「filename」という配列名だけで中身の「aaa.txt」と何故認識できるのでしょうか? 配列名ということで、先頭アドレスのみの情報しかないと思いました。 教えていただければ嬉しいです。

  • 特定した文字のカウント

    ご質問です。 テキストファイルを読み込んで、 その中に半角カンマ「,」のある数を調べる関数を 作りたいのですがどうすればよいのでしょうか。 また、得られた値を返したいのです。 下記の例でいいますと、 ooo()という関数内でカンマの数が必要で、ppp()を呼ぶ。そしてiをカウントしてooo()内でその値を使いたいのです。 よろしくお願いいたします。 void ppp(){ int ch,i,bh; FILE *fp; fp = fopen("a.txt", "r"); // ファイルオープン失敗か? if ( !fp ){ printf("ファイルオープンエラー\n"); return; } // 1文字ずつ読み込んで表示する i=1; bh=,; while( (ch = fgetc(fp)) >= 0 ){ if(ch == bh){ i=i+1; } } printf("%d",i); // ファイルクローズ fclose(fp); return i; }

  • ファイルの入出力

    学生です。まだ習い始めて間もないのですがよろしくお願いします。 27.000000,207.000000,116.000000 48.000000,90.000000,116.000000 48.000000,90.000000,116.000000       : テキストの中にある上記のカンマ区切りのデータをfscanfで読み込んで違うテキストに同じ数値を出力したいのですがうまく出力できません。 0.000000,0.000000,+NAN 0.000000,0.000000,+NAN 0.000000,0.000000,+NAN      : 数値は上記のように出力されてしまいます。 プログラムは以下の通りです。 main() { FILE *fp; double m[30][3]; int i,j; double e1,e2,e3; fp=fopen("data00.txt","r"); for(i=0;i<30;i++){  fscanf(fp,"%f,%f,%f\n",&e1,&e2,&e3);  m[i][0]=e1;  m[i][1]=e2;  m[i][2]=e3; } fclose(fp); fp=fopen("data01.txt","w"); for(j=0;j<30;j++){  fprintf(fp,"%f,%f,%f\n",m[j][0],m[j][1],m[j][2]); } fclose(fp); getch(); exit(0); } データの読み込みがうまくいってないのだと思いますがわかりません。 間違いがあったならご指摘お願いします。

  • ファイル入出力について教えて下さい。

    ご覧いただきありがとうございます。 数値を入力して、数値を出力する方法を教えて頂きたいです。 ・   ・   ・ fp = fopen( "a.txt", "a" ); for( i = 16383; i >= 0; i-- ) { fprintf( fp, "%d", i ); } fclose( fp ); ・   ・   ・ data = (int *)malloc(32768); fp = fopen( "a.txt", "r" ); for( i = 0, i <= 16383; i++ ) { fscanf( fp, "%d", data+i ); } fclose( fp ); ・   ・ ・ 以上の記述で、入力はうまくいくのですが、出力の際に数値でなくなってしまいます。どうしてでしょうか? ご存じの方がおりましたら、ご回答よろしくお願いいたします。

  • オープンモードについて

    この下のソースを実行するとファイルの中身が「97へ」と出ます。 この「へ」とは何なのでしょうか?97にしたいのですが、どうすればよいのでしょうか?またなぜこのような結果になってしまったのでしょうか? int main(void) { FILE *fp; int d=97; fp=fopen("txt.txt","w+"); fprintf(fp,"%d",d); fscanf(fp,"%d",&d); printf("%d",d); fclose(fp); return 0; } 環境はVCC++2005です。