kkamegawa's weblog

Visual Studio,TFS,ALM,VSTS,DevOps関係のことについていろいろと書いていきます。Google Analyticsで解析を行っています

Windows 7で文字列比較すると2は10よりも小さくできるよ

文字列で2と10を比較すると、10のほうが小さいと判定されます。リストボックスなどにこんな風に出るといわれたことありませんか?

  • 1
  • 10
  • 2

こんな感じ。lstrcmpやCompareStringといったAPIでは先頭の文字で判断しちゃうからこうなるんでしょうね。で、あまりにも不便だという声が多かったのか、Windows 7/Windows Server 2008 R2ではCompareString(Ex)に一つフラグ(SORT_DIGITSASNUMBERS)が追加されました。
CompareStringEx function (Windows)
CompareString function (Windows)
これを指定してほんとに2が10よりも小さいと判定されるのか、こんなコードで実験してみましょう。

#define WINVER 0x602
#include <windows.h>

LPCTSTR lpszCSTR[4] = {_T("ERROR"), _T("CSTR_LESS_THAN"), _T("CSTR_EQUAL"), _T("CSTR_GREATER_THAN"), };
TCHAR szNumString2[] = {_T("10")};
TCHAR szNumString3[] = {_T("2")};

// 2を10よりも小さいと判定させるフラグ(SORT_DIGITSASNUMBERS)を指定した
iCompareResult = CompareStringEx(LOCALE_NAME_SYSTEM_DEFAULT, SORT_DIGITSASNUMBERS, 
	szNumString2,  -1, szNumString3, -1, NULL, NULL, 0);
_tprintf(_T("CompareStringEx %s %s %s \n"), szNumString2, lpszCSTR[iCompareResult], szNumString3);

// フラグを指定しない(従来と同じ)比較
iCompareResult = CompareStringEx(LOCALE_NAME_SYSTEM_DEFAULT, 0, 
	szNumString2,  -1, szNumString3, -1, NULL, NULL, 0);
_tprintf(_T("CompareStringEx %s %s %s \n"), szNumString2, lpszCSTR[iCompareResult], szNumString3);

結果

CompareStringEx 10 CSTR_GREATER_THAN 2
CompareStringEx 10 CSTR_LESS_THAN 2

例ではCompareStringExを使っていますが、比較フラグはCompareStringと共通なのでCompareStringでも同じ結果になります。CompareStringExの方がLOCAL_NAME_SYSTEM_DEFAULTフラグが使えるのでソースコードが簡単になるだけという理由です(^^;。