Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/53.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 如何判断Delphi变量是否为空字符串?_String_Delphi_Delphi Xe_Variants - Fatal编程技术网

String 如何判断Delphi变量是否为空字符串?

String 如何判断Delphi变量是否为空字符串?,string,delphi,delphi-xe,variants,String,Delphi,Delphi Xe,Variants,变种总是很有趣的,是吗 我正在开发一个遗留应用程序,该应用程序上一次是在D2007中将其迁移到Delphi XE 在此期间,变体发生了相当大的变化 这行代码: if (VarType(Value) = varString) and (Value = '') then Exit; 返回True并在D2007中退出,但在Delphi XE中没有 我已将其更改为: if VarIsStr(Value) and (VarToStr(Value) = '') then Exit; 我不相

变种总是很有趣的,是吗

我正在开发一个遗留应用程序,该应用程序上一次是在D2007中将其迁移到Delphi XE

在此期间,变体发生了相当大的变化

这行代码:

if (VarType(Value) = varString) and (Value = '') then 
  Exit;
返回True并在D2007中退出,但在Delphi XE中没有

我已将其更改为:

if VarIsStr(Value) and (VarToStr(Value) = '') then
    Exit;
我不相信这是最好的方式。变体部门没有具体的要求来做这件事,我当然记得这是过去人们的一个问题。然而,一项搜索显示没有任何库函数或任何其他被接受的方式


是否有“正确”或更好的方法?

更新:特定于字符串以避免异常:

    if VarIsStr(Value) and (Length(VarToStr(v))=0) then ...
更新3:如果你想要更好的性能和更少的字符串堆内存浪费,试试这个。 假设字符串的长度为64K。上面的代码执行一个VarToStr并分配64K的UnicodeString堆空间来保存数据,这样我们就可以在BSTR的字符串末尾查找nul终止符,在其他类型中查找nil指针

下面的代码有点奇怪,因为通常不涉及变体的内部表示,但是David指出了错误,我重新测试了它,它似乎可以工作,尽管没有明示或暗示任何保证。这只小狗的单元测试会很好。在将来的某个日期,如果Delphi RTL gods决定重命名变量结构字段的内部表示,则需要更改下面的代码

function VarStrEmpty(v:Variant):Boolean;
var
  data:PVarData;
begin
    data := FindVarData(V);
  case data^.VType of
     varOleStr:
            result := (data^.VOleStr^=#0);
     varString:
            result := (data^.VString=nil);
     varUString:
            result := (data^.VUString=nil);
     else
      result := false;
  end;
end;

VarIsStr
是一种完全可行的方法。其实施方式如下:

function VarTypeIsStr(const AVarType: TVarType): Boolean;
begin
  Result := (AVarType = varOleStr) or (AVarType = varString)
    or (AVarType = varUString);
end;

function VarIsStr(const V: Variant): Boolean;
begin
  Result := VarTypeIsStr(FindVarData(V)^.VType);
end;
当然,您看到的变化实际上是由于D2009中的Unicode变化,而不是变体的变化。您的字符串将是
varUString
,也称为
UnicodeString
。当然,
VarIsStr
也会选择
AnsiString/varString
WideString/BSTR/varOleStr

如果您希望真正忠实地转换您的Delphi 2007代码,那么您可以编写:

if (VarType(Value) = varUString) and (Value = '') then 
  Exit;

确切地说,您需要做什么,只有您自己知道,但关键是您必须考虑新到达的
varUString

变体可以是数字或字符串

当变量(数字)的值为负值(-15)时,可能会出现问题

还有你的线路

(VarType(Value) = varString) and (Value = '')
((VarType(Value) = varString) and (Value = ''))
我总是要把


这是我的窍门。

Nick试图避免变体无法强制为字符串时出现的异常。这就是他需要第一次检查和短路评估的原因。我很难看到所有额外的复杂性带来了什么。对于空的OleStr,它也会给出一个错误的答案,因为它们被表示为一个空的wchar\t。还是我弄错了?与“”进行比较有什么不好?除非你用VartoString将其展平到一个单位分解,否则它并不总是有效。打个比方,这就像一个接一个地数你所有的便士,以确保你有。这是不必要和浪费的。这里所谓的优化在我看来显然是不成熟和毫无意义的。以这种方式编写代码会导致错误。你心照不宣地接受了这一点,说你可能错过了一些小案子。对我来说,编写如此复杂的代码,以至于您无法确定其正确性,这是毫无意义的。尤其是当存在琐碎且明显正确的替代方案时。另一方面,显然@Nick更喜欢这种方式,所以我可能会错过一些东西。请给我一个解释。
strlen
太浪费了。走这条线没有意义。我已经自由地以一种有效的方式进行了编辑。我还是觉得感觉像是预科生。但是你看顺便说一句,
v=''
是真的,如果我显式地将其分配给
v:=''-我猜有不止一个变量字符串子类型,可能是B_STR和其他类型,因此元素比较失败,即使内容是相同的。如果VarToStr(Value)=''
单独完成工作,@kobik这会失败吗?例如,当
Value
等于
Null
@DavidHeffernan,按照D5/D7中的预期工作。e、 g.
如果VarToStr(Null)='',那么beep
@kobik Null不是一个字符串,因为它不是一个字符串。您误解了这个问题。负数在这里不相关。关于()的第二点也是完全错误的。当
value
不是字符串时,所有情况都默认为true。这一逻辑与问题不符。
if VarToStrDef(value, '') = '' then