759403 ランダム
 HOME | DIARY | PROFILE 【フォローする】 【ログイン】

さすらいのプログラマ

FCSV

FCSV.h
#ifndef   __FILE_SCSV__
#define   __FILE_SCSV__
#include<stdio.h>
#include"SCSV.h"

typedef struct __fcsv {
  char *filename;                                // CSVファイルのファイル名
  FILE *fp;                                      // CSVファイルのファイルポインタ
  int buffer_length;                             // 読み込み用のバッファの長さ
  char *buffer;                                  // 読み込み用のバッファ
  int flag_eof;                                  // EOFフラグ
  int flag_open;                                 // ファイルオープンフラグ
  int record_count;                              // 読み込みレコード件数
  int nOffset;
  int record_length;
  LPSCSV pscsv;                                  // CSV分解
  
  int (*open)(struct __fcsv *pfcsv);
  int (*close)(struct __fcsv *pfcsv);
  int (*read)(struct __fcsv *pfcsv);
  int (*getCount)(struct __fcsv *pfcsv);
  int (*getItemCount)(struct __fcsv *pfcsv);
  char *(*getItem)(struct __fcsv *pfcsv, int idx);
  int (*setSepChar)(struct __fcsv *pfcsv, char cSep);
  int (*setBufferSize)(struct __fcsv *pfcsv, int nSize);
} FCSV, *LPFCSV;

LPFCSV FCSVCreate(char *filename);
int FCSVRelease(LPFCSV pfcsv);

#endif // __FILE_SCSV__
FCSV.c
#include<string.h>
#include"FCSV.h"

#define FCSV_FILE_NOT_OPEN                       0
#define FCSV_FILE_OPENED                         1
#define FCSV_EOF_OFF                             0
#define FCSV_EOF_ON                              1
#define FCSV_DEFAULT_BUFFER_SIZE                 512

static int FCSVOpen(struct __fcsv *pfcsv);
static int FCSVClose(struct __fcsv *pfcsv);
static int FCSVRead(struct __fcsv *pfcsv);
static int FCSVGetCount(struct __fcsv *pfcsv);
static int FCSVGetItemCount(struct __fcsv *pfcsv);
static char *FCSVGetItem(struct __fcsv *pfcsv, int idx);
static int FCSVSetSepChar(struct __fcsv *pfcsv, char cSep);
static int FCSVSetBufferSize(struct __fcsv *pfcsv, int nSize);

LPFCSV FCSVCreate(char *filename) {
  LPFCSV pfcsv;
  int len;

  // FCSV構造体の確保
  pfcsv = (LPFCSV)malloc(sizeof(FCSV));
  memset(pfcsv, '\0', sizeof(FCSV));

  // ファイル名の格納領域の確保
  len = strlen(filename);
  pfcsv->filename = (char *)malloc(len + 1);
  // ファイル名を保存
  strcpy(pfcsv->filename, filename);

  // 読み込み用バッファの確保
  pfcsv->buffer_length = FCSV_DEFAULT_BUFFER_SIZE;
  pfcsv->buffer = (char *)malloc(pfcsv->buffer_length);

  // SCSV
  pfcsv->pscsv = SCSVCreate();

  pfcsv->open = FCSVOpen;
  pfcsv->close = FCSVClose;
  pfcsv->read = FCSVRead;
  pfcsv->getCount = FCSVGetCount;
  pfcsv->getItemCount = FCSVGetItemCount;
  pfcsv->getItem = FCSVGetItem;
  pfcsv->setSepChar = FCSVSetSepChar;
  pfcsv->setBufferSize = FCSVSetBufferSize;
  
  return pfcsv;
}

int FCSVRelease(LPFCSV pfcsv) {
  // ファイルオープン済みの場合は、クローズする。
  if(pfcsv->flag_open == FCSV_FILE_OPENED)
    pfcsv->close(pfcsv);
  // 読み込みバッファの解放
  free(pfcsv->buffer);
  // ファイル名格納領域の解放
  free(pfcsv->filename);
  // SCSV
  SCSVRelease(pfcsv->pscsv);
  // FCSV構造体の解放
  free(pfcsv);

  return 0;
}

static int FCSVOpen(struct __fcsv *pfcsv) {
  // すでにオープンされている場合は、エラー
  if(pfcsv->flag_open == FCSV_FILE_OPENED)
    return -1;
  // ファイルオープン
  pfcsv->fp = fopen(pfcsv->filename, "r");
  if(pfcsv->fp == NULL)
    return -1;
  // フラグをオープン済みとする。
  pfcsv->flag_open = FCSV_FILE_OPENED;
  // 読み込み件数をリセット
  pfcsv->record_count = 0;
  // EOFフラグをリセット
  pfcsv->flag_eof = FCSV_EOF_OFF;
  
  return 0;
}

static int FCSVClose(struct __fcsv *pfcsv) {
  // オープンしていない場合はエラー
  if(pfcsv->flag_open == FCSV_FILE_NOT_OPEN)
    return -1;
  // クローズ
  fclose(pfcsv->fp);
  // フラグをオープン未済に設定
  pfcsv->flag_open = FCSV_FILE_NOT_OPEN;
  
  return 0;
}

static int FCSVRead(struct __fcsv *pfcsv) {
  char *p;

  // オープンされていない場合は、オープンする。
  if(pfcsv->flag_open == FCSV_FILE_NOT_OPEN) {
    if(pfcsv->open(pfcsv) < 0)
      return -1;
  }
  // EOFの場合は、エラー
  if(pfcsv->flag_eof == FCSV_EOF_ON)
    return -1;
  // 読み込む前にファイル位置を保存
  pfcsv->nOffset = ftell(pfcsv->fp);
  // 1行読み込む(バッファーの長さより長い場合の対応はまだ)
  if(fgets(pfcsv->buffer, pfcsv->buffer_length, pfcsv->fp)) {
    pfcsv->record_length = strlen(pfcsv->buffer);
    // 改行は消す。
    p = strchr(pfcsv->buffer, '\n');
    if(p) *p = '\0';
    // SCSVによる分解を行う。
    pfcsv->pscsv->set(pfcsv->pscsv, pfcsv->buffer);
    // 読み込み件数をカウントアップ
    pfcsv->record_count++;
  }
  else {
    // EOFの場合の処理
    pfcsv->flag_eof = FCSV_EOF_ON;
    // 念のため、SCSVをリセット
    pfcsv->pscsv->reset(pfcsv->pscsv);
    pfcsv->record_length = 0;
    return -1;
  }
  return 0;
}

static int FCSVGetCount(struct __fcsv *pfcsv) {
  return pfcsv->record_count;                    // 読み込み件数を返す。
}

static int FCSVGetItemCount(struct __fcsv *pfcsv) {
  return pfcsv->pscsv->getCount(pfcsv->pscsv);   // 読み込んだ行の項目数を返す。
}

static char *FCSVGetItem(struct __fcsv *pfcsv, int idx) {
  return pfcsv->pscsv->getItem(pfcsv->pscsv, idx);         // 指定項目を返す。
}

static int FCSVSetSepChar(struct __fcsv *pfcsv, char cSep) {
  return pfcsv->pscsv->setSepChar(pfcsv->pscsv, cSep);     // 分解文字を変更
}

static int FCSVSetBufferSize(struct __fcsv *pfcsv, int nSize) {
  // 読み込みバッファの大きさを変更する。
  free(pfcsv->buffer);
  pfcsv->buffer_length = nSize;
  pfcsv->buffer = (char *)malloc(pfcsv->buffer_length);
  return 0;
}
※転載禁止


Copyright (c) 1997-2019 Rakuten, Inc. All Rights Reserved.