本章では、MQDBフォーマットファイルの読み書きを行なうC言語用上位インタフェース関数である、MqRead(), MqCreate()両関数の概要を紹介し、併せて両関数を利用したプログラミングについて述べる。両関数の詳しい説明は、第6章に述べられている。
本節では、MqRead, MqCreate()両関数の概要を紹介する。
MqRead()は、MQDBフォーマットファイルを読み出すための上位インタフェースの1つであり、関数を1回呼び出すだけでファイル全ヘッダ、及び全データを読み出せるように設計されている。また、MqCreate()は、MQDBフォーマットファイルを作成するための上位インタフェースであり、同じく関数を1回呼び出すことにより、全ヘッダ、及び全データを作成することが可能である。またヘッダのアクセスについては、アクセス制御変数を利用することによる調節が可能で、不必要なヘッダを読み書きしないように設定できる。
本関数を利用すると、次章で述べる方法、すなわち、各ヘッダへのアクセス用関数をそのたび毎に呼び出す方法に比べて、コーディングが大変簡単になるほか、標準入出力の扱いなどが比較的楽である。
MQLIB用データファイルを作成する場合には、基本的に次のような手順を踏む。
- プログラムのインクルードファイルに、mqdb.hを追加する。このファイルをインクルードしないと、MQLIB関数や変数の定義などが使用できない。
- まず、MqAccess構造体変数を定義する。この変数は、ヘッダ作成関数が作成するヘッダを規定する。
- ヘッダのデータを格納するMqHeader構造体変数を用意する。
- 実際のデータの「受け皿」となるdouble *型変数を用意する。この変数には実際に出力されるデータを格納する。データの格納の順序であるが、チャンネル1のデータは配列の 0 〜 n-1 番目、チャンネル2のデータは n 〜 2n-1 番目といったように格納しておく。
- MQLIBの関数を使用する前に、必ずMqInit()関数を呼ぶ。この関数は、状況変数(第5.6節参照)を初期化し、ライブラリを利用できる状態にするために必ず必要となるものである。
- ファイル名を格納したchar *型変数を用意する。この変数にはファイル名を格納しておいてもよいし、もし標準出力を利用してデータを出力する場合には、NULLをセットしておいてもよい。
- MqAccess構造体変数を使って、アクセスしたいヘッダを選ぶ。具体的には、構造体の各メンバに、アクセスしたい場合にはMQ_YESを、アクセスしたくない場合にはMQ_NOを代入すればよい。すべてのヘッダにアクセスしたい場合には、ユーティリティ関数のMqSetAccessYes()を利用すれば、全メンバにMQ_YESがセットされる。また、ヘッダ1つだけにアクセスしたい場合には、まず、全メンバにMQ_NOをセットするユーティリティ関数MqSetAccessNo()を実行し、その後アクセスしたいメンバだけにMQ_YESを代入すればよい。
- MqCreate()を呼び出す。この関数は、引き渡されたMqAccess構造体変数の指定に従って、MqHeader構造体変数に格納されたデータを使ってヘッダを作成し、その後データ部を作成する。データファイルの作成が成功すれば、エラー値(グローバル変数であるMqErr.errno)はEMQNOERRORである。もし作成途上で何らかのエラーが発生した場合には、この変数に然るべき値が代入される。エラーの種類によって、エラーメッセージが出力されるだけでデータファイルの作成が続けられる場合と、データファイルの作成が異常終了する場合がある。詳しくは第5.4節を参照のこと。
以下は、MQDBフォーマットファイルを出力するプログラムの例である。基本的な構造だ
けを示してある。
#include
#include /* 必ずこのファイルをインクルードすること */
main()
{
MqAccess access; /* アクセス制御用変数 */
MqHeader header; /* ヘッダデータ格納用変数 */
char filename[] = "test.dat"; /* データファイル名 */
double *data; /* 実際のデータを格納するための変数 */
MqInit( "prog-1.00" ); /* ライブラリ初期化 */
MqSetAccessYes( &access ); /* すべてのヘッダを作成する */
:
: この部分で、MqHeader変数やdouble *変数へのデータの格納を行なう。
:
MqCreate( filename, &access, &header, data )
if( MqErr.errno == EMQNOERROR )
exit( EXIT_SUCCESS );
else
exit( EXIT_FAILURE );
}
MQLIB用データファイルを読み込むプログラムを作る場合には、次のようなプログラムを書く。
- プログラムのインクルードファイルに、mqdb.hを追加する。このファイルをインクルードしないと、MQLIB関数や変数の定義などが使用できない。
- まず、MqAccess構造体変数を定義する。この変数は、読み込み関数においてアクセスするヘッダを規定する。
- ヘッダのデータを格納するMqHeader構造体変数を用意する。
- 実際のデータの「受け皿」となるdouble *型変数を用意する。この変数はMqRead()から返されるデータ配列のポインタを受けとるために必ず用意されなくてはならない。
- プログラム初頭に、必ずMqInit()関数を呼ぶ。この関数は、状況変数(第5.6節参照)を初期化し、ライブラリを利用できる状態にするために必ず必要となるものである。
- ファイル名を格納したchar *型変数を用意する。この変数にはファイル名を格納しておいてもよいし、もし標準入力を利用してデータを受けとる場合には、NULLをセットしておいてもよい。
- MqAccess構造体変数を使って、アクセスしたいヘッダを選ぶ。具体的には、構造体の各メンバに、アクセスしたい場合にはMQ_YESを、アクセスしたくない場合にはMQ_NOを代入すればよい。すべてのヘッダにアクセスしたい場合には、ユーティリティ関数のMqSetAccessYes()を利用すれば、全メンバにMQ_YESがセットされる。また、ヘッダ1つだけにアクセスしたい場合には、まず、全メンバにMQ_NOをセットするユーティリティ関数MqSetAccessNo()を実行し、その後アクセスしたいメンバだけにMQ_YESを代入すればよい。
- MqRead()関数を呼び出す。この関数は、引き渡されたMqAccess構造体変数の指定に従って、ヘッダのデータをMqHeader構造体変数に読み込む。もしデータの読み込みが成功すれば、データの先頭のポインタを返す。もしデータの読み込みに失敗した場合には、NULLが返される。
データは、チャンネルの順番に格納される。すなわち、チャンネル1のデータは配列
の0 〜 n-1 番めまでに格納される。チャンネル2のデータは配列の n 〜 2n-1 番めまでに格納されている。
データを得る操作はこれで終りである。あとは必要に応じて、変数を別の処理用ルーチンに引き渡したり、ヘッダの内容に応じた処理を行なえばよい。
以下に、MQDBフォーマットファイルを読み込むプログラムの例を示す。このプログラムは、test.datというファイルからデータを読み込み、その最初のデータの内容を表示する。
#include
#include /* 必ずこのファイルをインクルードすること */
main()
{
MqAccess access; /* アクセス制御用変数 */
MqHeader header; /* ヘッダデータ格納用変数 */
char filename[] = "test.dat"; /* データファイル名 */
double *data; /* 実際のデータを格納するための変数 */
MqInit( "prog-1.00" ); /* ライブラリ初期化 */
MqSetAccessYes( &access ); /* すべてのヘッダにアクセスする */
/* もしデータの読み込みに失敗したらメッセージを出力 */
if( NULL == ( data = MqRead( filename, &access, &header )))
MqPerror( NULL );
printf( "%lf\n", data[0] ); /* データの最初を出力 */
}