ファイルの作成・書き込み・読み込みについて

このQ&Aのポイント
  • C言語を使用して、指定の条件でファイルを作成、書き込み、読み込みする方法について質問しています。
  • 具体的な動作例として、100個のcsvファイルを作成し、その中にデータを書き込む方法についても質問しています。
  • また、指定した条件に一致するデータを読み込む方法や、特定のデータを上書きする方法についても知りたいとしています。
回答を見る
  • ベストアンサー

ファイルの作成・書き込み・読み込みについて

ファイルの取り扱いについて、どのように記述すればいいのかが分かりません。 分からないことが多いので(1)~(4)の質問に分けています、Cの勉強は趣味程度にしかできていないので、詳しくご回答いただけると嬉しいです。 自分なりに書いてみます、間違いがあればご指摘宜しくお願いします。 (1)Aを頭文字にして100個のcsvファイルを作成 (a1,a2…a100) char A[100] FILE *fp; for(i=1;i<101;i++) { snprintf(A,sizeof A,"A%d.csv",i); if((fp = fopen(A,"w"))!=NULL) {exit(1);} } (2)A1を開きデータを入れる、この動作を同様に2~100で繰り返す。 A1に入れたいデータはx,y,zで1000行 fp = fopen("A1.csv","a"); for(z=1;z<11;z++) { for(y=1;y<11;y++) { for(x=1;x<11;x++) { fprintf(fp,"%d,%d,%d\n",x,y,z); } } } fclose(fp); これでこんな感じに書き込まれるはず・・・ 1,1,1 2,1,1 3,1,1  ・  ・  ・ 10,10,10 これを同様に2~100のファイルに対して一気に行いたいですが、書き方が分かりません。 (3)再びA1を開きx=10,Y=10の時のzの値を知りたい。 こんな事はできるのでしょうか? もし無理なら~行目のデータを呼び出す (4)そしてA1を開きx=10,Y=10の時の、zだけを上書き。 長くなってすいません、分からない事だらけなので宜しくお願いします。

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

  • ベストアンサー
回答No.6

#5 です。 回答プログラムだけで字数制限いっぱいになってしまいました。 あなたの質問は「ランダムアクセスの仕方を教えてください。」というものです。 http://ja.wikipedia.org/wiki/%E3%83%A9%E3%83%B3%E3%83%80%E3%83%A0%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9 ファイルは、1個作成しようが100個作成しようがやっていることは同じですから、N_FILES の値を好みに応じて変更してください。 プログラムの要点は  #define FORM "%4d,%4d,%4d,%10d\n"  #define FORM_SIZE 26 //一行当たり と出力形式を改行\nを含めて 26バイトに固定していることです。それによって任意 x,y,z点の値nを参照したり、変更したりできるようになっています。 とりあえず、あなたの希望に答えて、その都度ファイルをオープンするプログラムを  Database sample:   1. Create   2. Input   3. Show   4. Correct  Input number の表示順(1~4)に入力し、実行してみてください。 各作業毎にホルダー内のCSVファイルを確認すれば、どのような処理がなされているかわかると思います。 その他参照URL http://www9.plala.or.jp/sgwr-t/c/sec17.html http://www1.cts.ne.jp/~clab/hsample/File/File06/File06.html

ponntata
質問者

お礼

ご回答ありがとうございます、返事を書くのがすごく遅くなってしまいました。 こう言った操作が有った事を知らなかったので、大変勉強になりました。 本当にありがとうございました。

その他の回答 (5)

回答No.5

#include <stdio.h> #include <stdlib.h> //exit() #define N_FILES 1 #define X_MAX 3 #define Y_MAX 3 #define Z_MAX 3 #define FORM "%4d,%4d,%4d,%10d\n" #define FORM_SIZE 26 //一行当たり void _create(void); void _input(void); void _show(void); void _correct(void); FILE *open_file(char*,char*); int main(void) { int cmd; printf("Sample Database:\n"); printf("\t1. Create\n"); printf("\t2. Input\n"); printf("\t3. Show\n"); printf("\t4. Correct\n"); printf("Select one "); scanf("%d", &cmd); switch (cmd) { case 1: _create(); break; case 2: _input(); break; case 3: _show(); break; case 4: _correct(); break; default: printf("Try again.\n"); break; } return 0; } void _create(void) { char file_name[32]; int i; FILE *fp; for(i=0;i<N_FILES;i++){ sprintf(file_name,"A%d.csv",i); if((fp=fopen(file_name,"w"))==NULL){ printf("Can't open %s file.\n", file_name); exit(1); } } fclose(fp); } void _input(void) { int x,y,z,n=0; FILE *fp; fp=open_file("file name? ", "w+"); for(z=0;z<Z_MAX;z++){ for(y=0;y<Y_MAX;y++){ for(x=0;x<X_MAX;x++){ fprintf(fp,FORM,x,y,z,n++); } } } fclose(fp); } void _show(void) { int x,y,z,n,offset; FILE *fp; fp=open_file("file name? ","r"); printf("code x,y,z? "); scanf("%d,%d,%d",&x,&y,&z); offset=x + Y_MAX*y + X_MAX*Y_MAX*z; fseek(fp,FORM_SIZE*offset,SEEK_SET); fscanf(fp,"%d,%d,%d,%d", &x,&y,&z,&n); printf("dat(%d,%d,%d)= %d\n",x,y,z,n); fclose(fp); } void _correct(void) { int x,y,z,n,offset,value; FILE *fp; fp=open_file("file name? ","r+"); printf("code x,y,z? "); scanf("%d,%d,%d",&x,&y,&z); offset=x+Y_MAX*y+X_MAX*Y_MAX*z; fseek(fp,FORM_SIZE*offset,SEEK_SET); fscanf(fp,"%d,%d,%d,%d", &x,&y,&z,&n); printf("data(%d,%d,%d)= %d ? ",x,y,z,n); scanf("%d", &value); fseek(fp,FORM_SIZE*offset+15,SEEK_SET); fprintf(fp,"%10d\n",value); fclose(fp); } FILE *open_file(char *comment, char *mode) { char file_name[32]; FILE *fp; printf("%s",comment); scanf("%s",file_name); if((fp=fopen(file_name,mode))==NULL){ printf("Can't open %s file.\n", file_name); ext(1); } return fp; }

回答No.4

もとの質問の本筋から大きく外れてしまうが、以下は一般的な話です。 たいていの人は fclose の戻り値の確認を忘れがちですが、fclose の戻り値を必ず確認 すべきです。なぜなら、ファイルへの書き込み処理で実はエラーがあった、ということ が、ファイルのクローズ時に検出されるということは、ありえるからです。 つまり、ファイルクローズ時に何らかの異常が検出される可能性があるため、それをアプリ 側で補足できる必要があります。

回答No.3

ファイルを作成するまでの方法については、他の方の指摘通りですが、 ファイル出力というのは、挿入処理をすることはではないので 出力する桁数がかわってしまうと内容が壊れてしまいます。 なので、(4)の仕様を実現するために、 出力(fprintf)の時にフォーマットを指定しましょう。("%2d,%2d,%2d\n"とか) #テキストエディタを上書きモートで編集するつもりになれば感覚はつかめると思います。 # 以下、出力したファイルの内容はソートされていることが前提になりますけれど。。。 (3)については、上記の対応で1行のサイズが固定になるので 行数*(Nバイト+改行)の位置にfseekすればジャンプ(fseek)することは できるようになります。 ですがまぁ、取得した後の値もつかうでしょうし、 テキスト形式にこだわらなくてもよければ 構造体を利用するのがいいんじゃないでしょうか。 x,y,zの値を持つ構造体を直接ファイル出力することで ファイルないのどこにほしいデータがあるか計算して直接取得できるようになります。 # sizeof(構造体)*(x*y*z) バイト目

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.2

char A[100] FILE *fp; for(i=1;i<101;i++) { snprintf(A,sizeof A,"A%d.csv",i); fp = fopen(A,"a"); for(z=1;z<11;z++) { for(y=1;y<11;y++) { for(x=1;x<11;x++) { fprintf(fp,"%d,%d,%d\n",x,y,z); } } } fclose(fp); }

  • php504
  • ベストアンサー率42% (926/2160)
回答No.1

1と2を合体させたら char A[100] FILE *fp; int i, x, y, z; for(i=1;i<101;i++) { snprintf(A,sizeof A,"A%d.csv",i); if((fp = fopen(A,"w"))!=NULL) { for(z=1;z<11;z++) { for(y=1;y<11;y++) { for(x=1;x<11;x++) { fprintf(fp,"%d,%d,%d\n",x,y,z); } } } fclose(fp); } }

ponntata
質問者

補足

なるほど其れもありなんですね…。 でもできれば(1)~(4)を分けて(開いて閉じての動作を分ける)書きたいのですが、どうすれば良いのでしょうか?

関連するQ&A

  • テキストファイルの出力について

    今、学校の課題でC言語を使ってプログラムを作っています。 20000個のデータを読み込んで、200個ずつに区切り、別々のテキストファイルで出力するというものです。 最初につくったのは、以下の通りです。 *********************************************** FILE *fp; { int b,i=0; data[0][i]=trend_data[0][i]; data[1][i]=trend_data[1][i]; fp = fopen("D1.txt","w"); for(i=0;i<=199;i++){ fprintf(fp,"%8.8f %8.8f\n",data[0][i],data[1][i]); } fclose(fp); fp = fopen("D2.txt","w"); for(i=200;i<=399;i++){ fprintf(fp,"%8.8f %8.8f\n",data[0][i],data[1][i]); } fclose(fp); ・・・ ***************************************** これだと20000まで繰り返し記述しなければならずかなり困難だと思いました。そこで、ループを作ろうとしたのですが、テキストファイルをループを使って複数作成する方法がわかりません。 以下のようなプログラムを作ったのですが、テキストファイルが一つしか作られませんでした。 どのように記述すればよいのでしょうか? **************************************** FILE *fp; { int a,i=0; int b=1; int c=199; data[0][i]=trend_data[0][i]; data[1][i]=trend_data[1][i]; start: fp = fopen("D[1+b].txt","w"); for(i=a;i<=c;i++){ fprintf(fp,"%8.8f %8.8f\n",data[0][i],data[1][i]); if(i > c) c = c+200; a = a+200; b++; goto start; fprintf(fp,"%8.8f %8.8f\n",data[0][i],data[1][i]); fclose(fp); } } ****************************************** よろしくお願い致します。

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

    ご覧いただきありがとうございます。 数値を入力して、数値を出力する方法を教えて頂きたいです。 ・   ・   ・ 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 ); ・   ・ ・ 以上の記述で、入力はうまくいくのですが、出力の際に数値でなくなってしまいます。どうしてでしょうか? ご存じの方がおりましたら、ご回答よろしくお願いいたします。

  • csvファイルの横方向への改行について

    ある2次元配列があったとして, セルをちゃんと改行しつつcsvファイルに 書き込みをしようとしてるのですが 英字の方へ改行をする方法がわかりません. int a[4][4] ;   :   : FILE *file; file = fopen("condidate.csv","w"); for(int x = 0; x < 5 ; x++) { for(int y = 0; y < 5; y++) { fprintf(file,"%d\n", a[x][y]); } //改行←ここがわからない } fclose(file); csvファイル 1つの配列が1つのセルに入っている状態 ↓  A B C D _ _ _ _ 1 |1 1 1 1 2 |1 1 1 1 3 |1 1 1 1 4 |1 1 1 1 上記のものを作りたいです. よろしくお願いいたします.

  • 複数テキストファイルを読み込み、複数テキストファイルの出力

    質問は100個のテキストファイル(それぞれ10個のデータを含む)を読み込み、それぞれのテキストファイルから5個ずつデータを抽出し、200個のテキストファイルとして出力するというプログラムについての質問です。 以下が僕の作ったファイル出力部分のプログラムです。 /************/ void ecg_rr(fp,data_max) FILE *fp; { int b,i=0; int c=1; char fname[64]; data[0][i]=trend_data[0][i]; for(i=0;i<100;i++) sprintf(fname,"ss[%d].txt",1+i); fp = fopen(fname,"w"); fprintf(fp,"%4d\n",c); fprintf(fp,"%8.8f\n",data[0][0]); fprintf(fp,"%8.8f\n",data[0][2]); fprintf(fp,"%8.8f\n",data[0][4]); fprintf(fp,"%8.8f\n",data[0][6]); fclose(fp); sprintf(fname,"sk[%d].txt",1+i); fp = fopen(fname,"w"); fprintf(fp,"%4d\n",c); fprintf(fp,"%8.8f\n",data[0][1]); fprintf(fp,"%8.8f\n",data[0][3]); fprintf(fp,"%8.8f\n",data[0][5]); fprintf(fp,"%8.8f\n",data[0][9]); fclose(fp); } 複数ファイルの読み込み方がわからず、自分のプログラムだと1つのテキストファイルしか読み込めないので、16_4.batを作り、その中身を 16_4 読み込むテキストファイル名1.txt ss[1] 16_4 読み込むテキストファイル名1.txt sk[1] 16_4 読み込むテキストファイル名2.txt ss[2] 16_4 読み込むテキストファイル名2.txt sk[2] ・・・ とやったのですが、うまくいきませんでした。 どうすればよいのでしょうか。

  • ファイルへの書込み処理が異常に遅い

    以下のファイルへの書込みを行なうプログラムの処理速度が極端に遅く困惑しています。 -------------------------------------------------------------------------------- /*  文字列"0,"をファイルに約2MB出力するプログラム  (2000文字で改行、1行毎にfopen&fclose) */ #include<stdio.h> void main( int argc, char *argv[] ) {   FILE *fp;   for( int i = 0; i < 1000; i++ )   {     if( !(fp = fopen( "C:\hogehoge.log", "a" ) ) )     {       exit( 1 );     }     for( int j = 0; j < 1000; i++ )     {       fprintf( fp "0," );     }     fprintf( "\n" );     fclose( fp );   }   exit( 0 ); } -------------------------------------------------------------------------------- 処理時間は5分程度です。 出力する文字列を"0#"に変えると5~6秒で終了します。 カンマが入ると違うのでしょうか? OSはWinXP、コンパイラはVC++7.0です。 原因と解決策をご存知の方、よろしくご教示下さい。

  • ファイル

    c言語初心者です。 どなたか教えていただけませんか? これだとiが定義されないことになってしまいます。 #include<stdio.h> #include<stdlib.h> int main() { FILE *fp; fp=fopen("monai", "w"); if(fp==NULL){ fprintf(stderr,"ファイルのオープンに失敗しました。\n"); exit(0); } int i; for(i=1;i<=30;i++) { if(i<=9){ fprintf(fp," %d ",i); } else if(i%10==0) { fprintf(fp,"%d\n",i); } else { fprintf(fp,"%d ",i); } } fclose(fp); return 0; } ビルドもできません。

  • ファイルへの書き込み

    フォームに入力されたデータをCSVファイルに書き込みたいのですが、以下のようにすると追加で書き込みはできるのですが、ずっと改行されずに1行に書き込まれてしまうので、新しいデータを入れる際に改行されるようにしたいのですが、どのようにすればいいでしょうか? $fp = fopen(TEST_FILE,"a") or die("ファイルを開けません\n"); flock($fp, LOCK_EX); fputs($fp, "aaa")."\n"; flock($fp, LOCK_UN); fclose($fp);

    • ベストアンサー
    • PHP
  • 同時にファイル読み込み 書き込み

    現在、ヒストグラムのプログラムを作成しています。 まず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]++; } }

  • データの抜き取り、並び替え

    初心者です。よろしくお願いします。 今、私は3次元のデータを2次元にするプログラムを作りたいと思っています。データは1列226,981行で並んでいて、行は for(z=0;z<61;z++){ for(y=0;y<61;y++){ for(x=0;x<61;x++){ のように並んでいます。つまり行は61*61*61=226,981行あります。 このデータから例えばx=30のときのyz平面のデータを抜き取りたいと思っています。 データ例: -5.968777e+001 → (0,0,0) -4.980782e+001 → (1,0,0) -5.336652e+001 → (2,0,0) ・ ・ ・ -5.558537e+001 → (30,0,0) →抜き取り ・ ・ -5.595443e+001 → (61,0,0) ・ -5.867385e+001 → (30,1,0) →抜き取り ・ ・ ・ ・ -4.701691e+001 → (30,0,1) →抜き取り ・ ・ のように抜き取りたいと思っています。さらにこの抜き取ったデータを下のように       zの変化   →→→→→→→→→→→→→→→→→→→→→→  ↓(30,0,0)(30,0,1)(30,0,2)(30,0,3)  ↓(30,1,0)(30,1,1)(30,1,2)(30,1,3) ・・・・ y↓(30,2,0)(30,2,1)(30,2,2)(30,2,3) の↓ ・ 変↓ ・  化↓ ・  ↓ のように平面に並び替えなければなりません。使う関数や変数など初心者で、まったくわからず困っています。どうか助言やプログラミング例をいただけるとありがたいです。 下はファイルの入出力例から作った入出力プログラムです #include<stdio.h> #include<math.h> #include<string.h> #include<stdlib.h> void Make_Header(char*,int,int); //ヘッダファイル書き出し関数,このまま使用 #define T 226981 main() { /*変数宣言*/ int i; long j; static double data1[1][T]; FILE *fp_i, *fp_o; /*入力*/ printf("data in start\n"); fp_i = fopen("200113-HH-100a-IFFT-RS_ap(dB).dat", "rb"); //ファイルオープン,rbはオープン形式でバイナリファイル読み込み for(j = 0; j < T; j++){ for(i = 0; i < 1; i++){ fread(&data1[i][j],sizeof(static double),1,fp_i); } } fclose(fp_i); //開いたらちゃんと閉じる /*************************************** 処理部分 ***************************************/ /*出力*/ printf("write in start\n"); fp_o = fopen("eee.x00", "wb"); //ファイルオープン,wbはオープン形式でバイナリファイル書き出し for(j = 0; j < T; j++){ for(i = 0; i < 1; i++){ fwrite(&data1[i][j],sizeof(static double),1,fp_o); } } fclose(fp_o); //開いたらちゃんと閉じる Make_Header("eee.x00",1,T); //ErgoVistaのヘッダファイル情報を出力する関数,pixel(横数)とline(縦数)を出入 return 0; } /* ヘッダ情報書きこみのサブルーチン このまま使用*/ void Make_Header(char FN[], int pixel, int line) { char hd[40]="", text[40]; FILE *fhd; strncat(hd, FN, strlen(FN)-3); strcat(hd, "hdr"); if((fhd = fopen(hd, "w")) == NULL){ printf("error : cannot open [%s] (header file)\n", FN); exit(1); } fprintf(fhd, "FILE_TYPE = IMAGE \n"); fprintf(fhd, "IMAGE_LINES = %d \n",line); fprintf(fhd, "LINE_SAMPLES = %d \nEND\n",pixel); fclose(fhd); } このプログラムの処理部分を作りたいと思っています。どうかよろしくお願いします。

  • c言語の初心者なんですけど、ファイルからの読み込みで、文字や,や数字を

    c言語の初心者なんですけど、ファイルからの読み込みで、文字や,や数字を読み込みたいんですけど できません。 おしえてください。 プログラムは・・・・ #include<stdio.h> #include<ctype.h> int main(void){ char x[500][4]; FILE *fp; int i,j; fp=fopen("data2.txt","r"); for(i=0;i<500;i++){ for(j=0;j<4;j++){ fscanf(fp,"%c",&x[i][j]); } printf("%c,%d,%d,%d\n",x[i][0],x[i][1],x[i][2],x[i][3]); } fclose(fp); } ファイルは 田中,5,abc,18 鈴木,89,57,21 佐藤,,8,69 高橋,95,9,7

専門家に質問してみよう