バグ:Trimで指定文字が削除されないなんて詐欺に近い

Posted: 2013年01月28日

文字列操作(空白除去等)で気が付かずに書いてしまうバグを紹介します。

プログラムプログラム:

 #include <stdio.h>

 int main(int argc, char *argv[])
 {
    CString strSrc = _T(" ABCDEFG "); // 全角空白

    strSrc.Trim();

    // 処理

    return 0;
 }

このプログラムにどのように文字列操作(空白除去等)にバグが存在すると思いますか?

  • Trimの引数なしでは、全角空白は対象ではないため除去されない
  • UNICODE,MBCSではない場合は、引数に空白を入れても除去対象にはならない

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

 #include <stdio.h>

 int main(int argc, char *argv[])
 {
    CString strSrc = _T(" ABCDEFG "); // 全角空白

    // UNICODE,MBCSの場合
    strSrc.TrimLeft("  ");
    strSrc.TrimRight("  ");

    // それ以外の場合
    strSrc.Trim();
    strSrc.Trim((char) 0x81);
    // 処理

    return 0;
 }

解説解説:

CString Trimで_tcschrを呼び出しているため
_tcschrの挙動次第で処理が行われます。

UNICODE,MBCSの場合は、それぞれwcschr, _mbschrに置き換わるため問題ありませんが
問題が発生するstrchrを用いた場合この現象が発生します。

UNICODE, MBCS
TrimLeft,TrimRightはCStringで複数指定可能なため半角と全角を指定して対応しています。

それ以外
Trim((char) 0x81)を指定することで
全角空白(0x8140)を削除します。
0x81のみで判断を行うため他の文字が同様に削除される可能性もあります。
どうしても削除を行う場合は、 Trimの実装を真似して独自で実装する方法しかないと思います。

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

コメント