シリアライズ第6回〜可変長配列データの読み書き part.2〜


目次に戻る


今日紹介するのはフラグを使った可変長配列データの読み書きです。フラグを使った読み書きは大きさや種類が一定でないデータの配列を保存する時に有利です。
 
例としてドローイングソフトをあげます。
ドローイングソフトは点Xから点Yまで直線を引く。点Zから半径Rの円を描く。というように、描く手順を指示していき絵や図を描いていくソフトです。このため、「点Xから点Yまで直線を引く」というデータや「点Zから半径Rの円を描き内側を白で塗りつぶす。」というデータのように種類が異なるデータをまとめて扱う必要があるのです。
フラグを使ったデータの読み書きはこのようなデータ構造をもつアプリケーションに有効的です。
 
フラグを用いたデータの保存
/*
 * c:\work\data6.bin というファイルを作ります
 */
#include <stdio.h>

#define FILENAME "c:\\work\\data6.bin"

#define FLAG_EOF     0
#define FLAG_LINE    100
#define FLAG_CIRCLE  200

/* 保存するデータの型 */
typedef struct tagTLine {
    int x0,y0;
    int x1,y1;
} TLine;

typedef struct tagTCircle {
    int x,y;
    int radius;
} TCircle;

/* データ */
TLine GDataLine = {10,0,70,30};
TCircle GDataCircle = {50,40,60};

int main()
{
    FILE *fp = fopen( FILENAME , "wb" );    /* ファイルを開く。エラー処理は省略 */
    int flag;

    /* 直線データを書き込む */
    flag = FLAG_LINE;
    fwrite( &flag , sizeof( flag ) , 1 , fp );
    fwrite( &GDataLine , sizeof( GDataLine ) , 1 , fp );

    /* 円データを書き込む */
    flag = FLAG_CIRCLE;
    fwrite( &flag , sizeof( flag ) , 1 , fp );
    fwrite( &GDataCircle , sizeof( GDataCircle ) , 1 , fp );

    /* 終端フラグを書き込む */
    flag = FLAG_EOF;
    fwrite( &flag , sizeof( flag ) , 1 , fp );

    /* ファイルを閉じる */
    fclose( fp );

    return 0;
}

 
フラグを用いたデータをファイルから読み込む
/*
 * c:\work\data6.bin というファイルを作ります
 */
#include <stdio.h>

#define FILENAME "c:\\work\\data6.bin"

#define FLAG_EOF     0
#define FLAG_LINE    100
#define FLAG_CIRCLE  200

/* 保存するデータの型 */
typedef struct tagTLine {
    int x0,y0;
    int x1,y1;
} TLine;

typedef struct tagTCircle {
    int x,y;
    int radius;
} TCircle;

/* データ */
TLine GDataLine;
TCircle GDataCircle;

int main()
{
    FILE *fp = fopen( FILENAME , "rb" );   /* ファイルを開く。エラー処理は省略 */
    int flag;
 
    /* ファイルから読み込む */
    do {
       /* フラグを読み込む */
       fread( &flag , sizeof(flag) , 1 , fp );
 
       /* フラグが指す値によって場合分け */
       switch( flag ){
           case FLAG_LINE:
                fread( &GDataLine , sizeof( GDataLine ) , 1 , fp );
                break;
           case FLAG_CIRCLE:
                fread( &GDataCircle , sizeof( GDataCircle ) , 1 , fp );
                break;
       }
    } while( flag != FLAG_EOF );
 
    /* ファイルを閉じる */
    fclose( fp );
 
    /* 結果出力 */
    printf("LINE (%d,%d) - (%d,%d)\n",GDataLine.x0,GDataLine.y0,GDataLine.x1,GDataLine.y1 );
    printf("Circle (%d,%d),%d\n",GDataCircle.x,GDataCircle.y,GDataCircle.radius );
 
    return 0;
}



目次に戻る