string Delphi中是否有必要将字符串转换为WideString?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1024515/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it necessary to convert string to WideString in Delphi?
提问by Mariusz Schimke
I found a Windows API function that performs "natural comparison" of strings. It is defined as follows:
我找到了一个执行字符串“自然比较”的 Windows API 函数。它的定义如下:
int StrCmpLogicalW(
LPCWSTR psz1,
LPCWSTR psz2
);
To use it in Delphi, I declared it this way:
为了在 Delphi 中使用它,我是这样声明的:
interface
function StrCmpLogicalW(psz1, psz2: PWideChar): integer; stdcall;
implementation
function StrCmpLogicalW; external 'shlwapi.dll' name 'StrCmpLogicalW';
Because it compares Unicodestrings, I'm not sure how to call it when I want to compare ANSI strings. It seems to be enough to cast strings to WideString and then to PWideChar, however, I have no idea whether this approach is correct:
因为它比较Unicode字符串,所以当我想比较 ANSI 字符串时,我不确定如何调用它。将字符串转换为 WideString 然后转换为 PWideChar 似乎就足够了,但是,我不知道这种方法是否正确:
function AnsiNaturalCompareText(const S1, S2: string): integer;
begin
Result := StrCmpLogicalW(PWideChar(WideString(S1)), PWideChar(WideString(S2)));
end;
I know very little about character encoding so this is the reason of my question. Is this function OK or should I first convert both the compared strings somehow?
我对字符编码知之甚少,所以这就是我提出问题的原因。这个函数是否可以,或者我应该先以某种方式转换两个比较的字符串?
采纳答案by gabr
Keep in mind that casting a string to a WideString will convert it using default system codepage which may or may not be what you need. Typically, you'd want to use current user's locale.
请记住,将字符串转换为 WideString 将使用默认系统代码页将其转换,这可能是也可能不是您需要的。通常,您希望使用当前用户的语言环境。
From WCharFromChar
in System.pas:
从WCharFromChar
System.pas 中:
Result := MultiByteToWideChar(DefaultSystemCodePage, 0, CharSource, SrcBytes,
WCharDest, DestChars);
You can change DefaultSystemCodePage by calling SetMultiByteConversionCodePage.
您可以通过调用SetMultiByteConversionCodePage来更改 DefaultSystemCodePage 。
回答by Ian Boyd
The easier way to accomplish the task would be to declare your function as:
完成任务的更简单方法是将函数声明为:
interface
function StrCmpLogicalW(const sz1, sz2: WideString): Integer; stdcall;
implementation
function StrCmpLogicalW; external 'shlwapi.dll' name 'StrCmpLogicalW';
Because a WideString
variable isa pointer to a WideChar
(in the same way an AnsiString
variable isa pointer to an AnsiChar
.)
因为WideString
变量是指向 a 的指针WideChar
(就像AnsiString
变量是指向AnsiChar
.)
And this way Delphi will automatically "up-convert" an AnsiString to a WideString
for you.
这样,Delphi 会自动将 AnsiStringWideString
为您“向上转换”为 a 。
Update
更新
And since we're now in the world of UnicodeString
, you would make it:
既然我们现在在 的世界UnicodeString
,你会做到:
interface
function StrCmpLogicalW(const sz1, sz2: UnicodeString): Integer; stdcall;
implementation
function StrCmpLogicalW; external 'shlwapi.dll' name 'StrCmpLogicalW';
Because a UnicodeString
variable is still a pointer to a \0\0
terminated string of WideChars
. So if you call:
因为UnicodeString
变量仍然是指向\0\0
终止字符串的指针WideChars
。所以如果你打电话:
var
s1, s1: AnsiString;
begin
s1 := 'Hello';
s2 := 'world';
nCompare := StrCmpLogicalW(s1, s2);
end;
When you try to pass an AnsiString
into a function that takes a UnicodeString
, the compiler will automatically call MultiByteToWideChar
for you in the generated code.
当您尝试将 an 传递给采用AnsiString
a 的函数时,UnicodeString
编译器将自动MultiByteToWideChar
在生成的代码中调用您。
CompareString supports numeric sorting in Windows 7
CompareString 支持 Windows 7 中的数字排序
Starting in Windows 7, Microsoft added SORT_DIGITSASNUMBERS
to CompareString
:
从 Windows 7 开始,Microsoft 添加SORT_DIGITSASNUMBERS
到CompareString
:
Windows 7:Treat digits as numbers during sorting, for example, sort "2" before "10".
Windows 7:在排序时将数字视为数字,例如将“2”排在“10”之前。
None of this helps answer the actualquestion, which deals with when you have to convert or cast strings.
这些都无助于回答实际问题,该问题涉及何时必须转换或强制转换字符串。
回答by PatrickvL
There might be an ANSI variant for your function to (I haven't checked). Most Wide API's are available as an ANSI version too, just change the W suffix to an A, and you're set. Windows does the back-and-forth conversion transparantly for you in that case.
您的函数可能有一个 ANSI 变体(我还没有检查过)。大多数 Wide API 也可以作为 ANSI 版本使用,只需将 W 后缀更改为 A,就可以了。在这种情况下,Windows 会为您透明地进行来回转换。
PS: Here's an article describing the lack of StrCmpLogicalA : http://blogs.msdn.com/joshpoley/archive/2008/04/28/strcmplogicala.aspx
PS:这是一篇描述缺少 StrCmpLogicalA 的文章:http: //blogs.msdn.com/joshpoley/archive/2008/04/28/strcmplogicala.aspx
回答by NGLN
Use System.StringToOleStr
, which is a handy wrapper around MultiByteToWideChar
, see Gabr's answer:
使用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;
But then, Ian Boyd's solutionlooks and is much nicer!
但是,伊恩博伊德的解决方案看起来更好!