2.(レポート課題)ファイル入出力
2.1 データの読み込み
ファイルから1次元データを読み込む機能を作ります。幾つかのサンプルファイルがこちらに準備してありますので、適宜ダウンロードして使って下さい。
形式はすべてバイナリファイルです。従って、fopen関数でのモードは"rb"とする必要があります。読み込みにはfread関数を使います。ファイルの内部構造はこちら。
どのファイルも、その先頭に、格納されているデータのサイズ(個数)を示す情報がlong型整数として書き込まれています。ファイルをオープンした後、まずこのサイズ情報を読み込む必要があります。例えば、
long
length;
...
fread(&length,
sizeof(long), 1, fp);
などとすれば、lengthにサイズを読み込めます。そのあと、実際のデータ部分を読み込むわけですが、データはすべてdouble型になっています。適切なポインタに必要なメモリ領域を動的に確保した後、fread関数で一気にデータを読み込めばOKです。
double
*buf;
...
buf
= (double *)malloc(sizeof(double)*length);
...
fread(buf,
sizeof(double), length, fp);
動的なメモリ確保に自信が無くて、データ配列のサイズを固定して静的に定義しているひとは、例えば、
#define
SIZE 10
...
double
buf[SIZE];
...
fread(buf,
sizeof(double), SIZE, fp);
などとして、サイズが10と書いてあるファイルだけを選んで使うようにするとよいでしょう。ただし、これらのファイルも「先頭にlong型整数がある」という点は変わりませんので、それらを上述のように適当な変数を使って読み飛ばすか、fseek関数を使ってファイル位置指示子をsizeof(long)バイト(=8バイト)進めるかする必要があります。
構造体を使ってデータを管理しているひとは、例えば下のような構造体のメンバ変数に読み込めばよいでしょう(もちろんbufにはメモリ領域をmallocしてから)。
typedef
struct data_record {
long
length;
double
*buf;
}
RECORD;
2.2 データの書き出し
元データや演算結果を、テキストファイルとして書き出す機能をつけて下さい。
元データであっても演算結果であっても、配列(あるいは構造体)としての扱いは同じですから、同じ関数を使ってファイルに書き出すようにできます。
基本的には、配列の要素をひとつひとつfprintf関数で書き出していくだけです。先頭に配列のサイズを書き込む必要はありません。ただ、エクセルやgnuplot(森下先生によるgnuplot超入門)でグラフを書く場合のことを考えて、x軸の値として配列の要素番号もタブ区切りで書き込んでおくようにするとよいでしょう。
for
(i = 0; i < length; i++) {
fprintf(fp,
"%d\t%f\n", i, result[i]);
}
また、書き出す配列が存在するか、予めチェックするようにしたほうがよいでしょう。
以下は二次元データを扱うプログラムへの拡張にチャレンジしているひとのための情報です
(参考)二次元データファイルについて
二次元データについては、こちらにサンプルファイルがあります。
一次元データファイルと違い、始めに2つのlong型整数値として行数と列数が入っていますので、その両方をまず読み込んで下さい。それに続くdouble型データの構造は、行数N、列数Mとすると
data[0][0]
data[0][1]
...
data[0][M-1]
data[1][0]
data[1][1]
...
data[N-1][M-2]
data[N-1][M-1]
という順番に書き込まれています。