CSVファイル形式のデータをカンマ単位に文字列分割したいのですが、
文字列分割方法をweb上にて調べ、下記ソースを発見し使用していますが、
「,(カンマ)」が続く(値がNULLである)とその項目をとばしてしまいます。
何か良い手はないのでしょうか?
VC++に詳しい方是非教えてください。
int apart_by_pointer(char *strp[], const char *s)
{
int n = 0;
char *p, *ds;
ds = _strdup(s);
if ((p = strtok(ds, ",")) == NULL) {
free(ds);
return 0;
}
strp[n++] = _strdup(p);
while (p = strtok(NULL, ","))
strp[n++] = _strdup(p);
free(ds);
return n;
}
すいません。
追記です。
VC++でVBのsplit関数があれば教えてください。
>> 下記ソースを発見し使用していますが
この関数をどのように呼び出していますか。
呼び出し元関数を示してください。
strtokではこういう仕様なので、どうしようもないです。
strchrを使って、自力で分解するのがよいでしょう。
>> この関数をどのように呼び出していますか。
>> 呼び出し元関数を示してください。
上の関数 apart_by_pointer() には使用上の注意があるのですが。
ご存知かな。
MFC 系でスプリットをやってくれるクラス作ってみたんですよ。
まあ、初心者向けということで、効率とかは度外視で。
operator とか分かってもらえるといいなと。
#もしご存知なくばですが。
下の OnButton4() が実際の使用例です。
クラス宣言はコピペしておいて、OnButton4() のように使います。
というか OnButton4() でテストしたのみです。
環境はダイアログアプリです。
class CStrSplit
{
private:
static int WidthOf( char c )
{
byte cb = (byte)c;
return((( 0x80 < cb ) && ( cb < 0xA0 ) || ( 0xE0 <= cb ) && ( cb < 0xFD )) ? 2 : 1 );
}
public:
CString m_csDiv;
CStringArray m_acsStr;
BOOL m_bTrim;
CStrSplit( const char * szDiv, const char * strSrc = NULL, bool bTrim = false )
{
m_csDiv = szDiv ? szDiv : "";
m_bTrim = bTrim;
if( strSrc )
{
split( strSrc );
}
}
void split( const char * s )
{
m_acsStr.SetSize( 0 );
if( m_csDiv == "")
{
m_acsStr.SetAtGrow( 0,s );
}
else
{
CString vs,cs = s;
int pos,w, c = 0;
while(( pos = cs.FindOneOf( m_csDiv )) >= 0 )
{
w = WidthOf( cs[ pos ]);
if( m_bTrim )
{
vs = cs.Left( pos );
vs.TrimLeft();
vs.TrimRight();
m_acsStr.SetAtGrow( c++, vs );
}
else
{
m_acsStr.SetAtGrow( c++, cs.Left( pos ));
}
cs.Delete( 0, pos + w );
}
m_acsStr.SetAtGrow( c++, cs );
}
}
operator int()
{
return( m_acsStr.GetSize());
}
CString operator[]( int n )
{
if( n < m_acsStr.GetSize())
{
return( m_acsStr.GetAt( n ));
}
else
{
return( "" );
}
}
operator = ( const char * s )
{
split( s );
}
};
void CDt00Dlg::OnButton4()
{
const char * szDelimiter = ",、"; // 区切り文字
const char * szStringToBeSplit = "abc,def,GHI、JKL、mno,pqr";
CStrSplit sp( szDelimiter, szStringToBeSplit, false );
int c,ce = sp;
for( c = 0; c < ce; c ++ )
{
TRACE("%s\n", sp[c] );
}
sp = "きょうは、てんきが、、いいなっと"; // 再度別の文字を分離
ce = sp; // 分離した数を取得
for( c = 0; c < ce; c ++ )
{
TRACE("%s\n", sp[c] ); // 分離した個々の文字列を取得。
}
}
ツイート | ![]() |