델파이에서 문자열을 widestring으로 변환해야합니까?
-
06-07-2019 - |
문제
문자열의 "자연 비교"를 수행하는 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;
하지만, 이안 보이드의 해결책 외모와 훨씬 더 멋지다!