サンプル集  >  Borland C  >  セパレータ分割
セパレータ分割
2005/10/23

引数で受け取った文字列をセパレータ「,」で分解し表示します。

◆環境
OS Windows 2000 Professional
Compiler Borland C++ 5.5.1 for Win32

セパレータ分割を行う関数の中で、分割した文字列を格納する領域をmallocしています。

呼び元でメモリを解放しなければならないのが難点です。

BCC005.c
  1: 
  2: 
  3: 
  4: 
  5: 
  6: 
  7: 
  8: 
  9: 
 10: 
 11: 
 12: 
 13: 
 14: 
 15: 
 16: 
 17: 
 18: 
 19: 
 20: 
 21: 
 22: 
 23: 
 24: 
 25: 
 26: 
 27: 
 28: 
 29: 
 30: 
 31: 
 32: 
 33: 
 34: 
 35: 
 36: 
 37: 
 38: 
 39: 
 40: 
 41: 
 42: 
 43: 
 44: 
 45: 
 46: 
 47: 
 48: 
 49: 
 50: 
 51: 
 52: 
 53: 
 54: 
 55: 
 56: 
 57: 
 58: 
 59: 
 60: 
 61: 
 62: 
 63: 
 64: 
 65: 
 66: 
 67: 
 68: 
 69: 
 70: 
 71: 
 72: 
 73: 
 74: 
 75: 
 76: 
 77: 
 78: 
 79: 
 80: 
 81: 
 82: 
 83: 
 84: 
 85: 
 86: 
 87: 
 88: 
 89: 
 90: 
 91: 
 92: 
 93: 
 94: 
 95: 
 96: 
 97: 
 98: 
 99: 
100: 
101: 
102: 
103: 
104: 
105: 
106: 
107: 
108: 
109: 
110: 
111: 
112: 
113: 
114: 
115: 
116: 
117: 
118: 
119: 
120: 
121: 
122: 
123: 
124: 
125: 
126: 
127: 
128: 
129: 
130: 
131: 
132: 
133: 
134: 
135: 
136: 
137: 
138: 
139: 
140: 
141: 
142: 
143: 
144: 
145: 
146: 
147: 
148: 
149: 
150: 
151: 
152: 
153: 
154: 
155: 
156: 
157: 
158: 
159: 
160: 
161: 
162: 
163: 
164: 
165: 
166: 
167: 
168: 
169: 
170: 
171: 
172: 
173: 
174: 
175: 
176: 
177: 
178: 
179: 
180: 
181: 
182: 
183: 
184: 
185: 
186: 
187: 
188: 
189: 
190: 
191: 
192: 
193: 
194: 
195: 
196: 
197: 
198: 
199: 
/**********************************/
/* PROGRAM NAME : BCC005.cpp      */
/* AUTHOR       : ymlib.com       */
/* MAKE DAY     : 2005/10/23      */
/**********************************/

/********************/
/*                  */
/*  セパレータ分割  */
/*                  */
/********************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* プロトタイプ宣言 */
void getToken( const char* pBuf, char*** ppaList, int* iCnt );

int main( int argc, char** argv )
{
    char **ppaList;        /* 要素を格納した領域へのポインタ */
    int    iCnt;           /* 要素数                         */
    int    i;              /* ループカウンタ                 */

    fprintf( stdout, "BCC005 start!!\n" );

    /* パラメータチェック */
    if ( argc != 2 )
    {
        fprintf( stdout
               , "セパレータ分解する文字列を指定して下さい。\n"
               );
        exit( -1 );
    }

    /* 変数初期化 */
    ppaList = NULL;

    /* セパレータ分割 */
    getToken( argv[1], &ppaList, &iCnt );

    /* 結果表示 */
    fprintf( stdout, "要素数=[%d]\n", iCnt );
    for ( i = 0; i < iCnt; i++ )
    {
        fprintf( stdout
               , "%2d:[%s]\n"
               , i + 1
               , ppaList[i] );
    }

    /* 領域解放(2元目) */
    for ( i = 0; i < iCnt; i++ )
    {
        free( ppaList[i] );
    }

    /* 領域解放(1元目) */
    free( ppaList );

    fprintf( stdout, "BCC005 end!!\n" );

    return( 0 );
}

/************************************************************/
/*                                                          */
/* getToken()                                               */
/*                                                          */
/*   引数で受け取った文字列 paBuf をセパレータ「,」で区切り */
/* 2次元配列に格納し返す。                                 */
/*                                                          */
/************************************************************/
void getToken( const char* paBuf, char*** ppaList, int* iCnt )
{
    unsigned int i;               /* ループカウンタ          */
    unsigned int iLen;            /* paBufの長さ             */
    unsigned int iStart;          /* 要素の開始位置          */
    unsigned int iDataLen;        /* 要素の長さ              */

    int iToken;                   /* 要素数                  */
    int iMemSize;                 /* 確保するメモリのサイズ  */

    /* 引数がNULLの場合 */
    if ( paBuf == NULL )
    {
        *iCnt = 0;
        return;
    }

    /* 引数の文字列長を取得 */
    iLen = strlen( paBuf );

    /* 引数の文字列長が0バイトの場合 */
    if ( iLen == 0 )
    {
        *iCnt = 0;
        return;
    }

    /* 要素の数を数える */
    *iCnt = 1;
    for ( i = 0; i < iLen; i++ )
    {
        if ( paBuf[i] == ',' )
        {
            ( *iCnt )++;
        }
    }

    /* 確保する領域の計算 */
    iMemSize = sizeof( char** ) * ( *iCnt );

    /* 領域確保(1元目) */
    *ppaList = ( char** )malloc( iMemSize );

    /* 確保した領域の初期化 */
    memset( *ppaList, 0x00, iMemSize );

    /*********************************************/
    /* セパレータ「,」区切りで文字列を要素へ分解 */
    /*********************************************/

    iStart = 0;
    iToken = 0;
    for ( i = 0; i < iLen; i++ )
    {
        /* セパレータ「,」のチェック */
        if ( paBuf[i] == ',' )
        {
            /* データ長の計算 */
            iDataLen = i - iStart;

            /* 確保する領域の計算 */
            iMemSize = sizeof( char ) * ( iDataLen + 1 );

            /* 領域確保(2元目) */
            ( *ppaList )[iToken] = ( char* )malloc( iMemSize );

            /* 確保した領域の初期化 */
            memset( ( *ppaList )[iToken], 0x00, iMemSize );

            /* データを設定 */
            if ( iDataLen == 0 )
            {
                /* セパレータが連続した場合「,,」、 */
                /* 空文字を設定                     */
                strncpy( ( *ppaList )[iToken], "", 1 );
            }
            else
            {
                strncpy( ( *ppaList )[iToken]
                       , &paBuf[iStart]
                       , iDataLen
                       );
                ( *ppaList )[iToken][iDataLen] = 0x00;
            }

            /* 要素の開始位置をセパレータ「,」の次へ */
            iStart = i + 1;

            /* 要素数を加算 */
            iToken++;
        }
    }

    /**************/
    /* 最後の要素 */
    /**************/

    /* データ長の計算 */
    iDataLen = i - iStart;

    /* 確保する領域の計算 */
    iMemSize = sizeof( char ) * ( iDataLen + 1 );

    /* 領域確保(2元目) */
    ( *ppaList )[iToken] = ( char* )malloc( iMemSize );

    /* 確保した領域の初期化 */
    memset( ( *ppaList )[iToken], 0x00, iMemSize );

    if ( iDataLen == 0 )
    {
        /* セパレータが連続した場合「,,」、空文字を設定 */
        strncpy( ( *ppaList )[iToken], "", 1 );
    }
    else
    {
        strncpy( ( *ppaList )[iToken]
               , &paBuf[iStart]
               , iDataLen
               );
        ( *ppaList )[iToken][iDataLen] = 0x00;
    }

    return;
}

ビルドコマンドです。

make.bat
1: 
bcc32 -IC:\borland\bcc55\Include -LC:\borland\bcc55\Lib BCC005.c

◆実行結果
>BCC005.exe 1
BCC005 start!!
要素数=[1]
 1:[1]
BCC005 end!!

>BCC005.exe 11
BCC005 start!!
要素数=[1]
 1:[11]
BCC005 end!!

>BCC005.exe 11,,22,,33,,44,,55,,66
BCC005 start!!
要素数=[11]
 1:[11]
 2:[]
 3:[22]
 4:[]
 5:[33]
 6:[]
 7:[44]
 8:[]
 9:[55]
10:[]
11:[66]
BCC005 end!!

>BCC005.exe 1,,,,,,,,
BCC005 start!!
要素数=[9]
 1:[1]
 2:[]
 3:[]
 4:[]
 5:[]
 6:[]
 7:[]
 8:[]
 9:[]
BCC005 end!!

>BCC005.exe ,,,
BCC005 start!!
要素数=[4]
 1:[]
 2:[]
 3:[]
 4:[]
BCC005 end!!

>BCC005.exe
BCC005 start!!
セパレータ分解する文字列を指定して下さい。

▲ PageTop  ■ Home


Copyright (C) 2016 ymlib.com