GVKun编程网logo

是否需要在Delphi中将字符串转换为WideString?(delphi字符串转可执行代码)

23

在本文中,我们将带你了解是否需要在Delphi中将字符串转换为WideString?在这篇文章中,我们将为您详细介绍是否需要在Delphi中将字符串转换为WideString?的方方面面,并解答del

在本文中,我们将带你了解是否需要在Delphi中将字符串转换为WideString?在这篇文章中,我们将为您详细介绍是否需要在Delphi中将字符串转换为WideString?的方方面面,并解答delphi字符串转可执行代码常见的疑惑,同时我们还将给您一些技巧,以帮助您实现更有效的delphi AnsiString 和 WideString 互轉函數、Delphi WideString和Delphi 2009、delphi – 从RawByteString转换为字符串会自动调用UTF8Decode吗?、delphi – 基于任意格式将字符串转换为TDateTime

本文目录一览:

是否需要在Delphi中将字符串转换为WideString?(delphi字符串转可执行代码)

是否需要在Delphi中将字符串转换为WideString?(delphi字符串转可执行代码)

我发现一个Windows API函数执行字符串的“自然比较”。定义如下:
int StrCmpLogicalW(
    LPCWSTR psz1,LPCWSTR psz2
);

要在Delphi中使用它,我以这种方式宣布:

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

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

因为它比较了Unicode字符串,当我想比较ANSI字符串时,我不知道如何调用它。似乎足以将字符串放置到WideString,然后到FlideChar,但是我不知道这种方法是否正确:

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

我对字符编码知之甚少,这是我问题的原因。这个功能是否正常,或者我应该首先将比较的字符串转换成某种方式吗?

解决方法

请记住,将一个字符串转换为WideString会使用默认的系统代码页进行转换,该代码页可能是也可能不是您需要的。通常,您希望使用当前用户的区域设置。

从System.pas中的WCharFromChar:

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

您可以通过调用SetMultiByteConversionCodePage来更改DefaultSystemCodePage。

delphi AnsiString 和 WideString 互轉函數

delphi AnsiString 和 WideString 互轉函數

总结

以上是小编为你收集整理的delphi AnsiString 和 WideString 互轉函數全部内容。

如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。

Delphi WideString和Delphi 2009

Delphi WideString和Delphi 2009

我正在编写一个类,将宽字符串保存到二进制文件.我正在使用Delphi 2005,但该应用程序将被移植到Delphi 2010.我在这里感到非常不确定,有人可以确认:

> Delphi 2005 WideString与Delphi 2010 String完全相同
> Delphi 2005 WideString char以及Delphi 2010 String char保证始终为2个字节大小.

使用所有的Unicode格式,我不想被我的字符串中的一个字符串突然3字节宽或类似的东西.

编辑:找到这个:“我确实说UnicodeString,而不是WideString,WideString仍然存在,并且不变,WideString由Windows内存管理器分配,应该用于与COM对象交互,WideString直接映射到COM中的BSTR类型“.在http://www.micro-isv.asia/2008/08/get-ready-for-delphi-2009-and-unicode/

现在我更困惑了所以Delphi 2010的WideString与Delphi 2005 WideString不一样?应该使用UnicodeString吗?

编辑2:Delphi 2005中没有UnicodeString类型.

解决方法

对于您的第一个问题:WideString与D2010的字符串不完全相同. WideString是一直以来一样的COM BSTR类型.它由Windows管理,没有引用计数,所以每当你在某个地方通过它时,它会复制整个BSTR.

UnicodeString,它是D2009及其中的默认字符串类型,基本上是我们都知道和喜欢的AnsiString的UTF-16版本.它有一个引用计数,由Delphi编译器管理.

对于第二个,默认的char类型现在是WideChar,它们是与WideString一直使用的相同的字符.它是一个UTF-16编码,每个字符2个字节.如果将WideString数据保存到文件中,可以将其加载到UnicodeString中,而不会有麻烦.两种类型之间的区别与内存管理有关,而不是数据格式.

delphi – 从RawByteString转换为字符串会自动调用UTF8Decode吗?

delphi – 从RawByteString转换为字符串会自动调用UTF8Decode吗?

我想将任意二进制数据作为BLOB存储到sqlite数据库中.

使用此函数将数据添加为值:

procedure TsqliteDatabase.AddParamText(name: string; value: string);

现在我想将WideString转换为其UTF8表示,因此可以将其存储到数据库中.在调用UTF8Encode并将结果存储到数据库后,我注意到数据库中的数据不是UTF8解码的.相反,它在我的计算机的语言环境中被编码为AnsiString.

我运行以下测试来检查发生了什么:

type
  {$IFDEF Unicode}
  TBinary = RawByteString;
  {$ELSE}
  TBinary = AnsiString;
  {$ENDIF}

procedure TForm1.Button1Click(Sender: TObject);
var
  original: WideString;
  blob: TBinary;
begin
  original := 'ä';
  blob     := UTF8Encode(original);

  // Delphi 6:   ä (as expected)
  // Delphi XE4: ä  (unexpected! How did it do an automatic UTF8Decode???)
  ShowMessage(blob);
end;

在字符“ä”转换为UTF8之后,数据在内存中是正确的(“¤”),但是,只要我将TBinary值传递给函数(作为字符串或AnsiString),Delphi XE4就会执行“魔术类型转换“由于某些原因我不知道调用UTF8Decode.

我已经找到了一个解决方法来避免这种情况:

function RealUTF8Encode(AInput: WideString): TBinary;
var
  tmp: TBinary;
begin
  tmp := UTF8Encode(AInput);
  SetLength(result,Length(tmp));
  copyMemory(@result[1],@tmp[1],Length(tmp));
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  original: WideString;
  blob: TBinary;
begin
  original := 'ä';
  blob     := RealUTF8Encode(original);

  // Delphi 6:   ä (as expected)
  // Delphi XE4: ä (as expected)
  ShowMessage(blob);
end;

但是,RealUTF8Encode的这种解决方法对我来说看起来很脏,我想了解为什么简单的UTF8Encode调用不起作用以及是否有更好的解决方案.

解决方法

在Delphi的Ansi版本中(在D2009之前),UTF8Encode()返回UTF-8编码的AnsiString.在Unicode版本(D2009及更高版本)中,它返回一个UTF-8编码的RawByteString,其代码页为CP_UTF8(65001).

在Ansi版本中,ShowMessage()接受AnsiString作为输入,UTF-8字符串是AnsiString,因此它按原样显示.在Unicode版本中,ShowMessage()采用UTF-16编码的UnicodeString作为输入,因此UTF-8编码的RawByteString使用其指定的CP-UTF8代码页转换为UTF-16.

如果您实际上将blob数据直接写入数据库,您会发现它可能是也可能不是UTF-8编码,具体取决于您编写它的方式.但你的做法是错误的;在这种情况下,使用RawByteString是不正确的. RawByteString仅用作过程参数.不要将它用作局部变量.这是你问题的根源.从documentation:

The purpose of RawByteString is to reduce the need for multiple
overloads of procedures that read string data. This means that
parameters of routines that process strings without regard for the
string’s code page should typically be of type RawByteString.

RawByteString should only be used as a parameter type,and only in
routines which otherwise would need multiple overloads for AnsiStrings
with different codepages. Such routines need to be written with care
for the actual codepage of the string at run time.

对于Unicode版本的Delphi,而不是RawByteString,我建议您使用TBytes来保存您的UTF-8数据,并使用TEncoding对其进行编码:

var
  utf8: TBytes;
  str: string;
...
str := ...;
utf8 := TEncoding.UTF8.GetBytes(str);

您正在寻找一种在传递时不执行隐式文本编码的数据类型,而TBytes就是该类型.

对于Ansi的Ansi版本,您可以完全像您一样使用AnsiString,WideString和UTF8Encode.

但就个人而言,我建议一致地使用TBytes来获取您的UTF-8数据.因此,如果您需要一个支持Ansi和Unicode编译器的代码库(唉!),那么您应该创建一些帮助器:

{$IFDEF Unicode}
function GetUTF8Bytes(const Value: string): TBytes;
begin
  Result := TEncoding.UTF8.GetBytes(Value);
end;
{$ELSE}
function GetUTF8Bytes(const Value: WideString): TBytes;
var
  utf8str: UTF8String;
begin
  utf8str := UTF8Encode(Value);
  SetLength(Result,Length(utf8str));
  Move(Pointer(utf8str)^,Pointer(Result)^,Length(utf8str));
end;
{$ENDIF}

Ansi版本引入的堆分配比必要的多.您可能会选择编写一个更有效的帮助程序,直接调用WideCharToMultiByte().

在Unicode版本的Delphi中,如果由于某种原因您不想将TBytes用于UTF-8数据,则可以使用UTF8String.这是一个特殊的AnsiString,它总是使用CP_UTF8代码页.然后你可以写:

var
  utf8: UTF8String;
  str: string;
....
utf8 := str;

并且编译器将在幕后为您转换为UTF-16到UTF-8.我不推荐这个,因为它不支持移动平台,也不支持Ansi的Ansi版本(自Delphi 6以来已经存在UTF8String,但在Delphi 2009之前它不是真正的UTF-8字符串).也就是说,除其他原因外,为什么我建议您使用TBytes.我的理念是,至少在Unicode时代,存在本机字符串类型,并且任何其他编码都应该保存在TBytes中.

delphi – 基于任意格式将字符串转换为TDateTime

delphi – 基于任意格式将字符串转换为TDateTime

在Delphi 5中有没有办法将字符串转换为TDateTime,您可以在其中指定要使用的实际格式?

我正在处理一个工作处理程序,它接受各种工作站的任务。这些任务有一系列参数,其中一些是日期,但是(不幸的是,我的控制之外)它们作为字符串传递。由于作业可能来自不同的工作站,因此用于将日期格式化为字符串的实际日期时间格式可能(当然也是实际的)不同。

Googling,我发现唯一的快速解决方案是偷偷地更改ShortDateFormat变量,然后将其恢复到其原始值。因为ShortDateFormat是一个全局变量,而且我正在一个线程环境中工作,唯一的方法是通过同步每个对它的访问,这是完全不可接受的(和可撤销的)。

我可以将SysUtils单元的库代码复制到我自己的方法中,并调整它们使用指定的格式而不是全局变量,但我只是想知道是否有更多的东西,我错过了。

亲爱的,并且提前感谢,

威廉

UPDATE

更简洁地说:

我需要像StrToDate(或StrToDateTime)这样的东西,增加的选项是指定它应该用来将字符串转换为TDateTime的确切格式。

解决方法

我为FreePascal的dateutils单元创建了这样的例程,如果需要移植,它应该很容易地移植。

码:

http://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/packages/rtl-objpas/src/inc/dateutil.inc?revision=30628&view=co

(代码是文件末尾的最后一个(巨大的)过程)

文档:

http://www.freepascal.org/docs-html/rtl/dateutils/scandatetime.html

请注意,它不是formatdatetime的完整的反向,它有一些扩展:

> FormatDateTime的倒数不是100%的倒数,只是因为可以把例如时间令牌在格式字符串中两次,而scandatetime不知道选择哪个时间。
>像hn这样的字符串不能安全地反转。例如。 1:2(1分钟后2分钟)提供12,被解析为12:00,然后
错过了“n”部分的字符。

>尾随字符被忽略。
>不支持东亚格式化字符,因为它们只是窗口。
>没有MBCS支持。

>扩展

#9吃空白
>在空格结尾的模式是可选的。
>?匹配任何字符。
>引用上面的chars来真正匹配char。

(我相信这些意见稍微过时了,这个意义上,一些亚洲的支持后来被添加了,但我不确定)

我们今天的关于是否需要在Delphi中将字符串转换为WideString?delphi字符串转可执行代码的分享就到这里,谢谢您的阅读,如果想了解更多关于delphi AnsiString 和 WideString 互轉函數、Delphi WideString和Delphi 2009、delphi – 从RawByteString转换为字符串会自动调用UTF8Decode吗?、delphi – 基于任意格式将字符串转换为TDateTime的相关信息,可以在本站进行搜索。

本文标签: