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

さすらいのプログラマ

SCSV

SCSV.h
#ifndef   __SIMPLE_CSV__
#define   __SIMPLE_CSV__

#include<stdio.h>

typedef struct __scsv {
  int item_count;
  int count;
  int buffer_length;
  int length;
  char **items;
  char *buffer;
  char cSep;

  int (*set)(struct __scsv *pscsv, char *szSrc);
  int (*getCount)(struct __scsv *pscsv);
  char *(*getItem)(struct __scsv *pscsv, int idx);
  int (*reset)(struct __scsv *pscsv);
  int (*setSepChar)(struct __scsv *pscsv, char cSep);
} SCSV, *LPSCSV;

LPSCSV SCSVCreate();
int SCSVRelease(LPSCSV pscsv);

#endif // __SIMPLE_CSV__
SCSV.c
#include"SCSV.h"

#define SCSV_DEFAULT_BUFFER_SIZE                            256
#define SCSV_DEFAULT_ITEM_COUNT                             16
#define SCSV_DEFAULT_APPEND_BIT_OF_BUFFER_LENGTH            8
#define SCSV_DEFAULT_APPEND_BIT_OF_ITEM_COUNT               4

static int SCSVSet(struct __scsv *pscsv, char *szSrc);
static int SCSVGetCount(struct __scsv *pscsv);
static char *SCSVGetItem(struct __scsv *pscsv, int idx);
static int SCSVReset(struct __scsv *pscsv);
static int SCSVSetSepChar(struct __scsv *pscsv, char cSep);

LPSCSV SCSVCreate() {
  LPSCSV pscsv;
  int i;

  // SCSV構造体の確保
  pscsv = (LPSCSV)malloc(sizeof(SCSV));
  memset(pscsv, '\0', sizeof(SCSV));

  // バッファーの確保
  pscsv->buffer_length = SCSV_DEFAULT_BUFFER_SIZE;
  pscsv->buffer = (char *)malloc(pscsv->buffer_length);

  // 分解後の各項目へのポインタ格納領域の確保
  pscsv->item_count = SCSV_DEFAULT_ITEM_COUNT;
  pscsv->items = (char **)malloc(sizeof(char *) * pscsv->item_count);
  
  for(i = 0; i < pscsv->item_count; i++)
    pscsv->items[i] = NULL;

  // 区切り文字
  pscsv->cSep = ',';

  // 関数の登録
  pscsv->set = SCSVSet;
  pscsv->getCount = SCSVGetCount;
  pscsv->getItem = SCSVGetItem;
  pscsv->reset = SCSVReset;
  pscsv->setSepChar = SCSVSetSepChar;

  return pscsv;
}

int SCSVRelease(LPSCSV pscsv) {
  // バッファーの解放
  free(pscsv->buffer);
  // SCSV構造体の解放
  free(pscsv);

  return 0;
}

static int SCSVSet(struct __scsv *pscsv, char *szSrc) {
  int len, count, i;
  char *p;

  // 分解元となる文字列の長さ+1
  len = strlen(szSrc) + 1;
  pscsv->length = len;
  // バッファーに入りきらない場合は、確保しなおす。
  if(len > pscsv->buffer_length) {
    free(pscsv->buffer);
    // 256の倍数にする。
    pscsv->buffer_length = ((len >> SCSV_DEFAULT_APPEND_BIT_OF_BUFFER_LENGTH) + 1)
                           <<SCSV_DEFAULT_APPEND_BIT_OF_BUFFER_LENGTH;
    pscsv->buffer = (char *)malloc(pscsv->buffer_length);
  }
  // 区切り文字をカウントすることにより項目数を算出する。
  for(p = szSrc, count = 1; *p; p++) {
    if(*p == pscsv->cSep)
      count++;
  }
  // 各項目へのポインタ格納領域が不足している場合は、確保しなおす。
  if(count > pscsv->item_count) {
    free(pscsv->items);
    // 16の倍数とする。
    pscsv->item_count = ((count >> SCSV_DEFAULT_APPEND_BIT_OF_ITEM_COUNT) + 1)
                        << SCSV_DEFAULT_APPEND_BIT_OF_ITEM_COUNT;
    pscsv->items = (char **)malloc(sizeof(char *) * pscsv->item_count);
  }
  // 分解元となる文字列をバッファーにコピー
  strcpy(pscsv->buffer, szSrc);
  // 念のため、各項目へのポインタを初期化
  for(i = 0; i < pscsv->item_count; i++)
    pscsv->items[i] = NULL;
  // 区切り文字で分解する。
  for(p = pscsv->buffer, count = 0; *p; p++) {
    if(pscsv->items[count] == NULL)
      pscsv->items[count] = p;

    if(*p == pscsv->cSep) {
      *p = '\0';
      count++;
      pscsv->items[count] = p + 1;
    }
  }
  count++;
  pscsv->count = count

  return pscsv->count;
}

static int SCSVGetCount(struct __scsv *pscsv) {
  return pscsv->count;
}

static char *SCSVGetItem(struct __scsv *pscsv, int idx) {
  if(idx < 0 || idx > pscsv->count)
    return NULL;

  return pscsv->items[idx];
}

static int SCSVReset(struct __scsv *pscsv) {
  int i;

  pscsv->buffer[0] = '\0';
  pscsv->count = 0;
  for(i = 0; i < pscsv->item_count; i++)
    pscsv->items[i] = NULL;

  return 0;
}

static int SCSVSetSepChar(struct __scsv *pscsv, char cSep) {
  pscsv->cSep = cSep;
  return pscsv->cSep;
}
※転載禁止


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