- 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) ); }
この間の関数と比べて使い分けできそうな場面で使ってね。
この間のも今回のもそうだけど、「カンマ分解」って言ってるけどカンマ以外の文字でも分解できるよ。