2015年04月13日
今更知った文字列比較の落とし穴
先日、自前のISAMシステムを開発していたのだが、インデックス構築側(仮にサーバサイド)では見つかるのに、検索側(仮にクライアントサイド)では見つからないという奇妙な現象が発生した
よくよくしらべてみると、サーバサイドではソートの際にキーの比較に strcmp を使用しているのに対し、クライアントサイドでは stricmp を使用しているのに気が付いた
元々のインデックスはすべて大文字変換してから格納してあったので、両者に違いはないと思いこんでいたのだが、実はここが大きな落とし穴で、stricmp のMSDNでの仕様は、小文字に変換してから比較するという記述があったのだ
そこでは、サンプルとしてアンダースコア '_' を含む文字列比較が、 strcmp と stricmp とで異なる結果を返すという解説も記述してあった
そこで、クライアントサイド側でデバッグしてみると、確かに、 '_' を含むデータの個所で、インデックス判定が逆転するということがわかった(検索では bsearch_s API を利用していたので、大小が逆転すると見つからなくなってしまう)
以前の記憶(おそらくVC6時代)では、stricmp は大文字変換してから比較していると思いこんでいたので、今回も、あえてインデックスは大文字変換してから格納していたのだが、それが裏目に出た格好だ
これについては、クライアントサイドのコードを修正し、キーとターゲットを両方大文字に変換してから strcmp を使うことで正しい結果を得ることができた
いや〜、長年の思い込みは怖いですね
よくよくしらべてみると、サーバサイドではソートの際にキーの比較に strcmp を使用しているのに対し、クライアントサイドでは stricmp を使用しているのに気が付いた
元々のインデックスはすべて大文字変換してから格納してあったので、両者に違いはないと思いこんでいたのだが、実はここが大きな落とし穴で、stricmp のMSDNでの仕様は、小文字に変換してから比較するという記述があったのだ
そこでは、サンプルとしてアンダースコア '_' を含む文字列比較が、 strcmp と stricmp とで異なる結果を返すという解説も記述してあった
そこで、クライアントサイド側でデバッグしてみると、確かに、 '_' を含むデータの個所で、インデックス判定が逆転するということがわかった(検索では bsearch_s API を利用していたので、大小が逆転すると見つからなくなってしまう)
以前の記憶(おそらくVC6時代)では、stricmp は大文字変換してから比較していると思いこんでいたので、今回も、あえてインデックスは大文字変換してから格納していたのだが、それが裏目に出た格好だ
これについては、クライアントサイドのコードを修正し、キーとターゲットを両方大文字に変換してから strcmp を使うことで正しい結果を得ることができた
いや〜、長年の思い込みは怖いですね
【このカテゴリーの最新記事】
-
no image
-
no image
この記事へのコメント
コメントを書く
この記事へのトラックバックURL
https://fanblogs.jp/tb/3536745
※ブログオーナーが承認したトラックバックのみ表示されます。
この記事へのトラックバック