文字列分割について


ABC  2004-12-10 03:46:31  No: 55613

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;
}


ABC  2004-12-10 03:49:27  No: 55614

すいません。
追記です。
VC++でVBのsplit関数があれば教えてください。


なーめ  2004-12-10 04:50:01  No: 55615

>> 下記ソースを発見し使用していますが
この関数をどのように呼び出していますか。
呼び出し元関数を示してください。


REE  2004-12-10 05:42:47  No: 55616

strtokではこういう仕様なので、どうしようもないです。
strchrを使って、自力で分解するのがよいでしょう。


なーめ  2004-12-10 07:17:37  No: 55617

>> この関数をどのように呼び出していますか。
>> 呼び出し元関数を示してください。
上の関数 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] ); // 分離した個々の文字列を取得。
  }
}


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加