- 2015-12-21
- Visual C++
この間、カンマ分解関数作ったけど、クラス化バージョン作ってみたよ。
意味あるかって?自己満です。
//分解クラス
class CParse
{
public:
CParse( LPCTSTR , LPCTSTR , bool = true );
~CParse();
const INT_PTR GetCount() const;
LPCTSTR GetAt( INT_PTR ) const;
protected:
void Parse( LPCTSTR , bool );
LPTSTR* m_pszParse;
INT_PTR m_nSize;
LPTSTR m_szDelimiter;
};
//============================================================================
// 【機 能】 コンストラクタ
//
// 【説 明】 引数に設定された文字列を分解する
//
// 【入出力】 LPCTSTR (IN): 分解したい文字列
// LPCTSTR (IN): 分解対象デリミタ文字(カンマ等)
// bool (IN): 空文字も対象とするか true:する false:しない
//
// 【戻り値】 なし
//
// 【備 考】 文字列はNULL終端文字とすること。
//============================================================================
CParse::CParse( LPCTSTR pchInBuff, LPCTSTR pchDelimiter , bool boption /*=true*/ )
{
//NULLチェック
if ( pchInBuff == NULL || pchDelimiter == NULL )
return;
//初期化
m_pszParse = NULL;
m_nSize = 0;
m_szDelimiter = NULL;
//デリミタセット
size_t nLen = 0;
nLen = _tcslen(pchDelimiter);
m_szDelimiter = new TCHAR[nLen+1];
::ZeroMemory( m_szDelimiter, ((nLen+1) * sizeof(TCHAR)) );
memcpy( m_szDelimiter, pchDelimiter, ((nLen+1) * sizeof(TCHAR)) );
//分解
this->Parse( pchInBuff , boption );
}
//============================================================================
// 【機 能】 分解処理
//
// 【説 明】 引数に設定された文字列を分解する
//
// 【入出力】 LPCTSTR (IN): 分解したい文字列
// bool (IN): 空文字も対象とするか true:する false:しない
//
// 【戻り値】 なし
//
// 【備 考】 文字列はNULL終端文字とすること。
//============================================================================
void CParse::Parse( LPCTSTR pchInBuff , bool bOption )
{
int nArrCnt = 0; //配列数
if ( pchInBuff == NULL )
{
return;
}
//--------------------------------------------------------------------------
//カンマの数+1の分だけ要素確保
//--------------------------------------------------------------------------
LPCTSTR pchSearch = NULL;
LPCTSTR pInPnt = pchInBuff; //アドレスサーチ用
//---------------------------
// 要素数決定処理
//---------------------------
nArrCnt = 0;
pchSearch = _tcsstr( pInPnt, m_szDelimiter );
while ( pchSearch != NULL )
{
if ( bOption == false && pInPnt == pchSearch )
{
pInPnt = pchSearch + 1;
pchSearch = _tcsstr( pInPnt, m_szDelimiter );
continue;
}
nArrCnt++;
pInPnt = pchSearch + 1;
pchSearch = _tcsstr( pInPnt, m_szDelimiter );
}
this->m_nSize = nArrCnt + 1;
//---------------------------
// 要素確保
//---------------------------
size_t nLen = _tcslen(pchInBuff);
this->m_pszParse = new LPTSTR[this->m_nSize];
for ( int ii = 0; ii < this->m_nSize ; ii++ )
{
this->m_pszParse[ii] = new TCHAR[nLen+1];
::ZeroMemory( this->m_pszParse[ii], (nLen+1) * sizeof(TCHAR) );
}
//--------------------------------------------------------------------------
//指定文字分解処理
//--------------------------------------------------------------------------
pInPnt = pchInBuff; //アドレスサーチ用
int nYoso = 0;
pchSearch = _tcsstr( pInPnt, _T(",") );
while ( pchSearch != NULL )
{
if ( bOption == false && pInPnt == pchSearch )
{
pInPnt = pchSearch + 1;
pchSearch = _tcsstr( pInPnt, m_szDelimiter );
continue;
}
memcpy( this->m_pszParse[nYoso], pInPnt, (pchSearch - pInPnt) * sizeof(TCHAR) );
nYoso++;
pInPnt = pchSearch + 1;
pchSearch = _tcsstr( pInPnt, m_szDelimiter );
}
memcpy( this->m_pszParse[nYoso], pInPnt, _tcslen(pInPnt) * sizeof(TCHAR) );
}
//============================================================================
// 【機 能】 分解文字配列数取得
//
// 【説 明】 分解された文字配列数を取得する。
//
// 【入出力】 なし
//
// 【戻り値】 なし
//
// 【備 考】 インデックスは 0 から始まる為、サイズはインデックスの
// 最大値よりも1大きい値になります
//============================================================================
const INT_PTR CParse::GetCount() const
{
return m_nSize;
}
//============================================================================
// 【機 能】 分解文字取得
//
// 【説 明】 指定されたインデックスの文字列を取得する
//
// 【入出力】 INT_PTR (IN): 取得したい要素
//
// 【戻り値】 LPTSTR : 取得した文字列
//
// 【備 考】 引数には GetCount-1よりも大きい要素を指定した場合
// 戻り値はNULLになります
//============================================================================
LPCTSTR CParse::GetAt( INT_PTR nIndex ) const
{
if ( ( m_nSize -1 ) < nIndex )
{
return NULL;
}
return this->m_pszParse[nIndex];
}
//============================================================================
// 【機 能】 デストラクタ
//
// 【説 明】 後始末
//
// 【入出力】 なし
//
// 【戻り値】 なし
//
// 【備 考】 文字列はNULL終端文字とすること。
//============================================================================
CParse::~CParse()
{
for( int ii = 0; ii < m_nSize; ii++ )
{
if ( m_pszParse[ii] != NULL )
{
delete [] m_pszParse[ii];
m_pszParse[ii] = NULL;
}
}
if ( m_pszParse != NULL )
{
delete [] m_pszParse;
m_pszParse = NULL;
}
if ( m_szDelimiter != NULL )
{
delete [] m_szDelimiter;
m_szDelimiter = NULL;
}
}
使い方
TCHAR chBuff[500]={NULL};
memcpy( chBuff, _T("aa,bb,ccc,dd,,ee"), 500 );
CParse clParse( chBuff, _T(",") );
TCHAR chOut[500]={NULL};
for ( int ii = 0 ; ii < clParse.GetCount() ; ii++ )
{
_tcscpy( chOut, clParse.GetAt(ii) );
}
この間の関数と比べて使い分けできそうな場面で使ってね。
この間のも今回のもそうだけど、「カンマ分解」って言ってるけどカンマ以外の文字でも分解できるよ。







