除了“%s”以外的任何内容与Variant一起使用时,为什么Format会崩溃?

时间:2011-04-04 17:56:28

标签: delphi variants

我正在使用SysUtils.Format函数和variant值,我发现只有格式字符串为%s时此函数才有效。我检查了有关Format函数的文档,但是没有任何关于如何处理变量值的引用。

考虑这个简单的应用程序:

{$APPTYPE CONSOLE}

uses
  Variants,
  SysUtils;

procedure TestFormat;
var
  v : Variant;
begin
  v:=100;
  writeln(Format('The VarType of v is %s',[VarTypeAsText(VarType(v))]));
  writeln(Format('The value of v is %s',[v]));//ok

  v:='100';
  writeln(Format('The VarType of v is %s',[VarTypeAsText(VarType(v))]));
  writeln(Format('The value of v is %s',[v]));//ok

  v:=100;
  writeln(Format('The VarType of v is %s',[VarTypeAsText(VarType(v))]));
  writeln(Format('The value of v is %d',[v]));//raise a EConvertError exception EConvertError: Format '%d' invalid or incompatible with argument
end;


begin
  try
     TestFormat;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  readln;
end.

这是一个错误还是此功能的简单限制?

我在Delphi 5,Delphi 2007和Delphi XE中检查过这种行为。

2 个答案:

答案 0 :(得分:12)

这是功能的限制。在Delphi XE中,SysUtils中的相关部分从10870行开始,如下所示:

@CvtVariant:
        CMP     CL,'S'
        JNE     @CvtError

任何变量参数都会调用此方法。 CL寄存器具有该特定参数的格式字符串所需的类型,对于任何不同于“S”的内容,都会引发异常。

答案 1 :(得分:10)

这是该功能的限制。要获得功能更丰富的Format版本,请尝试使用JCL中的WideFormat函数。 (我是它的作者。)它支持各种类型的变体,布尔和TClass。它还接受%p格式的字符指针类型,以及索引参数的Int64和Variant值。

尽管有一些扩展,它大约一年前从JCL发行版中删除了,因为它的主要目标是Delphi 5,它没有提供Format的原生WideString版本,并且JCL不再支持Delphi 5包含它的最后一个版本是3140