- 2015-12-17
- Visual C++
結構昔、VCのカンマ分解関数を作ったけど、
この辺参照
これはこれでいいんだけど開発の中ではMFCを使わないで実装したいってケースが多々ある。ので、作ったよ。
//============================================================================ // 【機 能】 配列数決定関数 // // 【説 明】 文字列分解の配列を // // 【入出力】 LPCTSTR (IN) : 分解したい文字列 // LPCTSTR (IN) : 分解対象デリミタ(カンマ等) // bool (IN) : 空文字を配列対象とするか(true:する false:しない) // // 【戻り値】 0未満:エラー // 0以上:出力パラメータに設定した配列数 // // 【備 考】 //============================================================================ int ArrayDecision( LPCTSTR pchInBuff , LPCTSTR pchDelimiter, bool boption ) { int nArrCnt = 0; //配列数 if ( pchInBuff == NULL || pchDelimiter == NULL ) { return -1; } //-------------------------------------------------------------------------- //カンマの数+1の分だけ要素確保 //-------------------------------------------------------------------------- LPCTSTR pchSearch = NULL; LPCTSTR pInPnt = pchInBuff; //アドレスサーチ用 //--------------------------- // 要素数決定処理 //--------------------------- nArrCnt = 0; pchSearch = _tcsstr( pInPnt, pchDelimiter ); while ( pchSearch != NULL ) { if ( boption == false && pInPnt == pchSearch ) { pInPnt = pchSearch + 1; pchSearch = _tcsstr( pInPnt, pchDelimiter ); continue; } nArrCnt++; pInPnt = pchSearch + 1; pchSearch = _tcsstr( pInPnt, pchDelimiter ); } return nArrCnt+1; } //============================================================================ // 【機 能】 分解関数 // // 【説 明】 インプットに指定された文字列を指定デリミタ毎に配列に設定する。 // // 【入出力】 LPCTSTR (IN) : 分解したい文字列 // const size_t (IN) : 分解後文字列に指定したい文字列バッファサイズ // LPCTSTR (IN) : 分解対象デリミタ(カンマ等) // bool (IN) : 空文字を配列対象とするか(true:する false:しない) // LPTSTR* (OT) : 分解した文字列の配列 // // 【戻り値】 0未満:エラー // 0以上:出力パラメータに設定した配列数 // // 【備 考】 呼び出し元でArrayDecisionを呼び配列を決定してから呼ぶ事。 //============================================================================ void DelimiterParse( LPCTSTR pchInBuff, const size_t nBuffSize, LPCTSTR pchDelimiter, bool boption, LPTSTR* pchOutBuff ) { int nArrCnt = 0; //配列数 if ( pchInBuff == NULL ) { return; } //-------------------------------------------------------------------------- //カンマ分解処理 //-------------------------------------------------------------------------- LPCTSTR pchSearch = NULL; LPCTSTR pInPnt = pchInBuff; //アドレスサーチ用 pInPnt = pchInBuff; //アドレスサーチ用 int nYoso = 0; pchSearch = _tcsstr( pInPnt, pchDelimiter ); while ( pchSearch != NULL ) { if ( boption == false && pInPnt == pchSearch ) { pInPnt = pchSearch + 1; pchSearch = _tcsstr( pInPnt, pchDelimiter ); continue; } memcpy( pchOutBuff[nYoso], pInPnt, (pchSearch - pInPnt) * sizeof(TCHAR) ); nYoso++; pInPnt = pchSearch + 1; pchSearch = _tcsstr( pInPnt, pchDelimiter ); } memcpy( pchOutBuff[nYoso], pInPnt, _tcslen(pInPnt) * sizeof(TCHAR) ); return; }
以下、使い方。
int nArrCnt; LPTSTR* ppOut =NULL; nArrCnt = ArrayDecision( chBuff , _T(","), true ); if ( nArrCnt > 0 ) { ppOut = new LPTSTR[nArrCnt]; for ( int ii = 0; ii < nArrCnt ; ii++ ) { ppOut[ii] = new TCHAR[sizeof(chBuff)/sizeof(TCHAR)]; ::ZeroMemory( ppOut[ii], sizeof(chBuff) ); } } DelimiterParse( chBuff, sizeof(chBuff), _T(","), true, ppOut ); for ( int ii = 0 ; ii < nArrCnt ; ii++ ) { _tcscpy( chOut, ppOut[ii] ); } for( int ii = 0; ii < nArrCnt; ii++ ) { if ( ppOut[ii] != NULL ) { delete [] ppOut[ii]; ppOut[ii] = NULL; } } if ( ppOut != NULL ) { delete [] ppOut; ppOut = NULL; }
こんなかんじ。
TCHAR を char、LPTSTR を char*、LPCTSTR を const char*、_tcsstr を strstr に置き換えればUNIXでも動くと思うよ。UNIXでは試してないけどね。
クラス化したバージョンも作ってみたから、近日中にアップするよ。クラス化してもあまり意味はなさそうだけどね。