バグ:文字列から指定文字列を抜き出し

Posted: 2012年12月06日

文字列から指定文字列を抜き出し処理でよく書いてしまうバグを紹介します。
文字列中から特定の文字列を探し、それ以降の文字列を取得するたぐいの処理です。

プログラムプログラム:

 #include  <stdio.h>
 #include <stdlib.h>

 int main(int argc, char *argv[])
 {
    CString strSrc = _T("1234567890");
    CString strDest;

    // 文字列の抜き出し
    int nIndex = szSrc.Find(_T("56"));
    strDest = szSrc.Mid(nIndex); // strDest=567890

    // 処理

    return 0;
 }

このプログラムにどのような指定文字列を抜き出し処理のバグがあると思いますか?

  • Findでエラーになることを考慮していない
  • srcに表(0x955C)で検索値が(0x5C)の場合Findが成功する。

改善版プログラム改善版プログラム:

 #include  <stdio.h>
 #include <stdlib.h>

 int main(int argc, char *argv[])
 {
    CString strSrc = _T("1234567890");
    CString strDest;

    // 文字列の抜き出し
    char *pFoundWord = _tcsstr(strSrc, _T("56"));
    if (pFoundWord == NULL) {
        return -1;
    }
    int nIndex = pFoundWord - ((LPTCSTR)strSrc);
    strDest = szSrc.Mid(nIndex); // strDest=567890

    // 処理

    return 0;
 }

※このプログラムは、ビルド時に以下のプリプロセッサ(define)されていることを期待しています。
 _MBCS、_UNICODE

解説解説:

_tcsstrを用いることで多バイト文字列対応の検索を行うことが可能です。
※実際には、_MBCSを定義する必要があるため_mbsstrが多バイト対応版

_tcsstrは、返却値が文字列のアドレスを返すため
見つかったアドレス-先頭アドレスでインデックスを求め
Midを行なっています。
他の方法もある(CStringのコンストラクタに返却値を入れる等)と思いますが今回は修正前と合わせる形で〜

_mbs関数は多バイト対応と思ってよさそうなため
他の処理で同様の問題に陥った場合は、_mbs
関数を探して使ってみるといいかもしれません。

カテゴリー: バグ, プログラム | タグ: , , , | コメント無し »

コメント