1 周目に計測した生体情報データを読み込み、プログラムにより信号処理を行うが、その際にファイルの 入出力が必要となる。実験前半ですでに学習しているが必要に応じて本資料を参考にすること。
■以下のようにすると指定したファイルを読み込むことができる(詳細は後から記述)。 int i;
double ---;
char fname[100]; // fname はファイル名のために宣言する. //これで100 文字までのファイル名を読める
FILE *data_in; //変数と同じく最初に宣言.printf などの予約語と同じにしない data_in=fopen("test.dat","r") //プログラム本体 fclose(data_in); ◎ファイルポインタとは ファイルに関する操作をするときは FILE 型で定義されるファイルポインタを宣言する.慣れるまでは 単純に「ファイルを開いたり綴じたりを設定する変数」程度の認識でよい. 読み込み用のファイルを扱う ファイルポインタに「out」とか「write」とか書き込みをイメージさせる単語は混乱してしまうので使わな い. ◎ファイルポインタへのファイルアクセスの指示:
fopen
これによりファイルポインタdata_out(アスタリスクは不要)には「test.dat」というファイルを「読み込 み=read モードで」用意しなさい という設定が行われる.モードは「書き込み w」「読み込み r」「追加参考資料
ファイル入出力: ファイルの読み込み
4S-RO ロボティクス実験
FILE *data_in;
data_in=fopen("test.dat","
r
")
ファイルを開くときの決まりごと。rは read、読み込みモード,つ まりファイルからデータを読み込むモードとしてアクセスする.これ をwにすると write、つまりファイルを作成して書き込むからモード となる。 今の場合は同じフォルダ内にあるtest.dat を読み込みなさい,とい うこと.Char 型変数 fname[100]に scanf でファイル名を入れて、fopen("sin.dat","r") を fopen(fname,"r")とすることで任意のフ ァイル名をオープンできる。
書き込み a」がある.w で書きこむときにはは追加ではないのでおなじファイル名を指定すると前のファ イルは消されて上書きされるので注意が必要である. また,指定がない場合は実行プログラムとおなじフォルダのファイルを読むので別のフォルダにファイルが ある場合はエラーとなる. ◎ファイルを開いたら閉じる 使ったら片づける,開けたら閉める.ファイルもオープンしたらクローズする.ファイルはfopen の段 階でアクセス可能な状態になっている.そのままの状態にしておいてプログラムを閉じてしまうとファイル は不安定な状態で待機することになるのでとても危険である.ゆえに,プログラムの最後あるいは用が済ん だ段階で必ずクローズすること.( )の中には閉じたいファイルを操作しているファイルポインタ名を入 れる.ファイル名ではない. ただし,読み込みファイルは ① 指定したファイルが同じフォルダ内に存在すること ② 指定したファイルが C で扱えるデータであること.グラフなどがあるエクセルデータは読めない という条件を忘れないこと. では,書き込みにたいして何が異なるのかというと, ■
fscanf 関数
プログラム中で実際にファイル内のデータを読み込む “ ”内の書式は実際のデータ列および型と一致させる. A B C この例では,読み込むファイルの中身がそれぞれ A: 1 列データで,型は int B: 2 列データの「タブ区切り」,変数は int と float(double). C: 2 列データの「カンマ区切り」で,変数は int と char 型. のようにファイルによって異なる.したがって,fscanf(data_in,”%d”,&a);
1 10 2 3 5 1 0.1 10 0.3 2 1.5 3 2.0 5 1.5 1 , a 10, b 2, c 3, d 5, efclose(data_in) ◎
fclose(test.dat) ×
◎これらの例では,例えばwhile 文を利用してデータを配列に入れていくとすると
※元データが改行してあっても,fscanf に改行記号¥n は不要
※カンマ区切りはfscanf にカンマを入れればよい ◎実際の読み取り
ファイルでデータを読むときはファイルが何行あるか分からない事が普通である.そこで,
ようにするのが一般的である.ここでいうEOF は End Of File の頭文字でこの記号があると「ここでファ イルはおわりです」という意味である.
なお,エクセルで自分で打ち込んだデータは最後に「EOF」を打ち込んでいないので読み込むと空のセル も読み続けるてしまうので注意すること.
以下のようにwhile の条件部分で読み取って,それが EOF じゃなければという繰り返しにする.「時間と 電圧値データのタブ区切り2 列データを配列に読み取る」場合は以下のようになる.
i=0; x_sum=0.0; ↓End of File の略 while(fscanf(data_in,"%lf\t%lf",&t[i],&x[i])!=EOF) { ↑この時点で t,x にデータは格納される x_sum+=x[i];//読み込んだデータをすぐに x_sum に足す i ++; } fclose(data_in);//この後読み込まないのですぐにクローズしている data_number=i; x_ave=s_sum/(double)data_number; この例では読み込みと同時に合計値も算出している.これはパターンとして覚えてしまったも良い.配列が 必要かどうかはケースバイケースとなる.配列を使う場合はデータ個数がいくらか分からないので多めに用 意しておくか動的に確保する.
ファイルを読み込む場合は,読み込むべき
ファイルの形式を一度確認する必要がある
A 一列の場合
fscanf(data_in,”%d”,&n[i]);
B 二列でデータがタブ区切りの場合の場合
fscanf(data_in,”%d\t%f”,&n[i],&x[i]);while を使って EOF を検出するまでデータを読む
C データがカンマ区切りの場合,char 型の場合
fscanf(data_in,”%d,%c”,&n[i],&c[i]);
※カンマ区切りはfscanf にカンマを入れればよい ※char 型は読み取りが%c になる.2 バイト文字は %c%c で一文字ファイル入出力:
ファイルの書き込み
int i;
double x[50];
char fname[100]; // fname はファイル名のために宣言する
FILE *data_out; data_out=fopen("sin.dat","w") for (i=0;i<50;i++) { x[i]=(double)i; fprintf(data_out,"%ld\t%lf\n",i,x[i]); } fclose(data_out); 実際の出力部分は,printf でディスプレイに出力していたことを fprintf にして出力先をファイルにするだ けである.(fprintf では画面に出てこないので確認用のprintf と併用することを推奨) ◎ファイルへデータを書きこむ部分は, ※fopen でファイル名を指定するとき以外は,プログラムにて直接ファイル名を指定する場面はない. 必ずファイルポインタを通して,そのファイルポインタに指定されているファイルをあつかう. 同じ名前 書き込みはw.書き込みモードとしてアクセスする. ※ファイル名に日本語は使えるが,「半角英数字+拡張子」を使 う.日本語フォルダ/ファイル名,全角スペースは危険. ※すでにあるファイルと同じ場合は上書きされる.自分のフォ ルダ内で実行し,システムファイルや大事なデータと同じ名 前にしない! fprintf は printf の書式に[どのファイルポインタに対し て?]が追加されるだけ。 今の場合は ファイルポインタ data_out、つまりはファイル名 sin.dat に書き込め、と言 う事。 printf( "%ld\t%lf\n",i,x[i]);
fprintf(data_out,"%ld\t%lf\n",i,x[i]);
こちらもオープンしたファイルは必ず閉じて終了(重要!)
fprintf(data_out,"%ld\t%lf\n",i,x[i]);
fprintf(data_out,"あいうえお\n");
◎複数のファイルを扱う場合