カテゴリー
C++

Visual C++/MFCライブラリ CSVカンマ区切りの処理

Visual C++ と MFC ライブラリは長い間使っているけど、他の言語のライブラリにはカンマ区切りの文字列を一発で配列に収めて返してくれる split 関数なるものが普通にあります。あらためて MFC CString にはそれがないことを認識しました。むかし、そのような処理をやったことがあったので、そのコードを抜粋しました。

以下、コード抜粋

    CString str = "111,222,333,444,555,,aaa,bbb,ccc,ddd,eee,fff";
    CArray<CString,CString> arr;

    // カンマ区切りを配列に格納
    arr.RemoveAll();
        
    int iStart = 0;
    int iPos = -1;

    CString restoken;
    iPos = str.Find(',', iStart);

    while(iPos > -1)
    {
        restoken = str.Mid(iStart, iPos - iStart);
        arr.Add(restoken);
        printf("Resulting token: %sn", restoken);

        iStart = iPos + 1;
        iPos = str.Find(',', iStart);

        if (iPos == -1)
        {
            restoken = str.Mid(iStart);
            arr.Add(restoken);
            printf("Resulting token: %sn", restoken);
        }
    }

出力結果

Resulting token: 111
Resulting token: 222
Resulting token: 333
Resulting token: 444
Resulting token: 555
Resulting token:
Resulting token: aaa
Resulting token: bbb
Resulting token: ccc
Resulting token: ddd
Resulting token: eee
Resulting token: fff

CSVファイルによっては、各列データををダブルクォーテーションで囲む場合もあるので、それは対応していません。;-)

また、MSDN CStringT::Tokenize のサンプル トークンの区切り文字をカンマにすると良さそうです。
※ 但し、カンマとカンマに文字が何もない場合(赤字の部分)は、その列は無視して次の列をトークンとして読み込むようです。CSV ファイルの処理で、空き列も処理する必要がある場合は要注意です。

以下、MSDN サンプルを一部変更して

    CAtlString str( "111,222,333,444,555,,aaa,bbb,ccc,ddd,eee,fff" );
    CAtlString resToken;
    int curPos= 0;

    resToken= str.Tokenize(",",curPos);
    while (resToken != "")
    {
        printf("Resulting token: %sn", resToken);
        resToken= str.Tokenize(",",curPos);
    }

出力結果

Resulting token: 111
Resulting token: 222
Resulting token: 333
Resulting token: 444
Resulting token: 555
Resulting token: aaa
Resulting token: bbb
Resulting token: ccc
Resulting token: ddd
Resulting token: eee
Resulting token: fff

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください