문제

문자열의 "자연 비교"를 수행하는 Windows API 기능을 찾았습니다. 다음과 같이 정의됩니다.

int StrCmpLogicalW(
    LPCWSTR psz1,
    LPCWSTR psz2
);

델파이에서 사용하기 위해 나는 이런 식으로 선언했다.

interface
  function StrCmpLogicalW(psz1, psz2: PWideChar): integer; stdcall;

implementation
  function StrCmpLogicalW; external 'shlwapi.dll' name 'StrCmpLogicalW';

비교하기 때문입니다 유니 코드 문자열, ANSI 문자열을 비교하고 싶을 때 어떻게 호출하는지 잘 모르겠습니다. 끈을 넓게 만들고 pwidechar에 캐스팅하는 것으로 충분한 것 같습니다. 그러나이 접근법이 올바른지 전혀 모릅니다.

function AnsiNaturalCompareText(const S1, S2: string): integer;
begin
  Result := StrCmpLogicalW(PWideChar(WideString(S1)), PWideChar(WideString(S2)));
end;

캐릭터 인코딩에 대해 거의 알지 못하므로 이것이 제 질문의 이유입니다. 이 기능은 괜찮습니까? 아니면 비교 된 문자열을 먼저 변환해야합니까?

도움이 되었습니까?

해결책

현악기에 문자열을 캐스팅하면 기본 시스템 코딩을 사용하여이를 변환하여 필요한 것일 수도 있고 아닐 수도 있습니다. 일반적으로 현재 사용자의 로케일을 사용하려고합니다.

에서 WCharFromChar System.pas :

Result := MultiByteToWideChar(DefaultSystemCodePage, 0, CharSource, SrcBytes,
  WCharDest, DestChars);

호출하여 기본값을 변경할 수 있습니다 setmultibyteconversioncodepage.

다른 팁

작업을 수행하는 더 쉬운 방법은 기능을 다음과 같이 선언하는 것입니다.

interface
   function StrCmpLogicalW(const sz1, sz2: WideString): Integer; stdcall;

implementation
   function StrCmpLogicalW; external 'shlwapi.dll' name 'StrCmpLogicalW';

a WideString 변하기 쉬운 ~이다 A에 대한 포인터 WideChar (같은 방식으로 AnsiString 변하기 쉬운 ~이다 에 대한 포인터 AnsiChar.)

그리고 이런 식으로 Delphi는 자동으로 ANSSESTRING을 WideString 당신을 위한.

업데이트

그리고 우리는 지금 세계에 있기 때문에 UnicodeString, 당신은 그것을 만들 것입니다 :

interface
   function StrCmpLogicalW(const sz1, sz2: UnicodeString): Integer; stdcall;

implementation
   function StrCmpLogicalW; external 'shlwapi.dll' name 'StrCmpLogicalW';

a UnicodeString 변수는 여전히 a에 대한 포인터입니다 \0\0 종료 된 문자열 WideChars. 그래서 당신이 전화하면 :

var
    s1, s1: AnsiString;
begin
    s1 := 'Hello';
    s2 := 'world';

    nCompare := StrCmpLogicalW(s1, s2);
end;

당신이 통과하려고 할 때 AnsiString a UnicodeString, 컴파일러가 자동으로 호출됩니다 MultiByteToWideChar 생성 된 코드에서 당신을 위해.

비교는 Windows 7에서 숫자 정렬을 지원합니다

Windows 7에서 시작하여 Microsoft는 덧붙였습니다 SORT_DIGITSASNUMBERS 에게 CompareString:

윈도우 7: 예를 들어 "10"전에 "2"를 정렬하는 데 분류하는 동안 숫자를 숫자로 취급하십시오.

이 중 어느 것도 대답하는 데 도움이되지 않습니다 실제 문자열을 변환하거나 캐스트해야 할 때를 다루는 질문.

귀하의 기능에 대한 ANSI 변형이있을 수 있습니다 (확인하지 않았습니다). 대부분의 넓은 API는 ANSI 버전으로도 사용할 수 있으며 W 접미사를 A로 변경하면 설정됩니다. Windows는이 경우 귀하를 위해 투명하게 전환합니다.

추신 : 다음은 strcmplogicala의 부족을 설명하는 기사입니다. http://blogs.msdn.com/joshpoley/archive/2008/04/28/strcmplogicala.aspx

사용 System.StringToOleStr, 그것은 편리한 포장지입니다 MultiByteToWideChar, 보다 Gabr의 대답:

function AnsiNaturalCompareText(const S1, S2: string): integer;   
var
  W1: PWideChar;
  W2: PWideChar;
begin
  W1 := StringToOleStr(S1);
  W2 := StringToOleStr(S2);
  Result := StrCmpLogicalW(W1, W2);
  SysFreeString(W1);
  SysFreeString(W2);
end;

하지만, 이안 보이드의 해결책 외모와 훨씬 더 멋지다!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top