Frage

fand ich eine Windows-API-Funktion, die „natürliche Vergleich“ von Strings führt. Es ist wie folgt definiert:

int StrCmpLogicalW(
    LPCWSTR psz1,
    LPCWSTR psz2
);

Um es in Delphi zu verwenden, ich erklärte es so:

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

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

Weil es vergleicht Unicode Strings, ich bin nicht sicher, wie es rufen, wenn ich wollen ANSI-Zeichenfolgen vergleichen. Es scheint genug zu sein, Strings Wide zu werfen und dann zu PWideChar aber ich habe keine Ahnung, ob dieser Ansatz richtig ist:

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

Ich weiß sehr wenig über Zeichencodierung so das der Grund meiner Frage. Ist diese Funktion OK oder sollte ich zuerst konvertieren beide die verglichenen Strings irgendwie?

War es hilfreich?

Lösung

Beachten Sie, dass eine Zeichenfolge in einem Wide Casting konvertiert es Standard-System-Codepage verwendet, die möglicherweise oder möglicherweise nicht, was Sie brauchen. Typischerweise würde, Sie möchten aktuellen Benutzers Gebietsschema verwenden.

Von WCharFromChar in System.pas:

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

Sie können DefaultSystemCodePage ändern, indem Aufruf SetMultiByteConversionCodePage .

Andere Tipps

Je einfacher Weg, um die Aufgabe zu erfüllen wäre, um Ihre Funktion zu erklären, wie:

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

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

Da eine WideString Variable ist ein Zeiger auf einen WideChar (in gleicher Weise eine AnsiString Variable ist ein Zeiger auf einen AnsiChar.)

Und auf diese Weise Delphi automatisch "up-convert" ein Ansistring zu einem WideString für Sie.

Update

Und da wir jetzt in der Welt der UnicodeString sind, dann würden Sie es machen:

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

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

Da eine UnicodeString Variable noch ein Zeiger auf ein \0\0 terminierten String von WideChars ist. Also, wenn Sie anrufen:

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

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

Wenn Sie versuchen, eine AnsiString in eine Funktion zu übergeben, die eine UnicodeString nimmt, wird der Compiler automatisch MultiByteToWideChar für Sie in den generierten Code aufrufen.

CompareString unterstützt numerische Sortierung in Windows 7

Starten in Windows 7, Microsoft hinzugefügt SORT_DIGITSASNUMBERS auf CompareString :

  

Windows 7:. Treat Ziffern als Zahlen während des Sortierens, beispielsweise sortieren "2" vor "10"

All dies hilft, beantworten Sie die ist Frage, die mit beschäftigt, wenn Sie konvertieren oder gegossene Saiten.

Es kann eine ANSI-Variante für Ihre Funktion sein (ich nicht überprüft haben). Die meisten Weit API sind als eine ANSI-Version auch nur das W-Suffix zu einem A ändern, und Sie werden eingestellt. Windows macht die Hin-und-her Umwandlung in transparenter Weise für Sie in diesem Fall.

PS: Hier ist ein Artikel den Mangel an StrCmpLogicalA beschreiben: http://blogs.msdn.com/joshpoley/archive/2008/04/28/strcmplogicala.aspx

Verwenden Sie System.StringToOleStr , die um MultiByteToWideChar eine handliche Wrapper finden Sie unter < a href = "https://stackoverflow.com/a/1025852/757830"> Gabr Antwort :

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;

Aber dann Ian Boyd Lösung aussieht und ist viel schöner!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top