gpt4 book ai didi

delphi - 如何使用 Move 连接多个字符串?

转载 作者:行者123 更新时间:2023-12-03 15:06:44 25 4
gpt4 key购买 nike

如何使用 Move 连接字符串数组。我尝试了这个,但我只是不知道如何让“移动”操作正常工作。

program Project2;

{$POINTERMATH ON}

procedure Concat(var S: String; const A: Array of String);
var
I, J: Integer;
Len: Integer;
begin
Len := 0;
for I := 0 to High(A) do
Len := Len + Length(A[I]);

SetLength(S, Length(S) + Len);

for I := 0 to High(A) do
Move(PWideChar(A[I])[0], S[High(S)], Length(A[I]) * SizeOf(WideChar));
end;

var
S: String;
begin
S := 'test';
Concat(S, ['test', 'test2', 'test3']);
end.

最佳答案

我会像这样编写这个函数:

procedure Concat(var Dest: string; const Source: array of string);
var
i: Integer;
OriginalDestLen: Integer;
SourceLen: Integer;
TotalSourceLen: Integer;
DestPtr: PChar;
begin
TotalSourceLen := 0;
OriginalDestLen := Length(Dest);
for i := low(Source) to high(Source) do begin
inc(TotalSourceLen, Length(Source[i]));
end;
SetLength(Dest, OriginalDestLen + TotalSourceLen);

DestPtr := PChar(Pointer(Dest)) + OriginalDestLen;
for i := low(Source) to high(Source) do begin
SourceLen := Length(Source[i]);
Move(Pointer(Source[i])^, DestPtr^, SourceLen*SizeOf(Char));
inc(DestPtr, SourceLen);
end;
end;

这是相当不言自明的。并发症是由空字符串引起的。当启用范围检查时,任何对空字符串的索引字符的尝试都会导致异常。

要处理这种复杂情况,您可以针对 Move 调用中涉及的字符串之一为空的情况添加 if 测试。我更喜欢不同的方法。我宁愿将字符串变量转换为指针。这会绕过范围检查,但也允许省略 if 语句。

Move(Pointer(Source[i])^, DestPtr^, SourceLen*SizeOf(Char));

人们可能想知道如果 Source[i] 为空会发生什么。在这种情况下,Pointer(Source[i])nil,您可能会遇到访问冲突。事实上,没有错误,因为第三个参数指定的移动长度为零,并且 nil 指针实际上从未被取消引用。

另一行注释在这里:

DestPtr := PChar(Pointer(Dest)) + OriginalDestLen;

我们使用 PChar(Pointer(Dest)) 而不是 PChar(Dest)。后者调用代码来检查 Dest 是否为空,如果是,则生成一个指向单个空终止符的指针。我们希望避免执行该代码,并直接获取 Dest 中保存的地址,即使它是 nil

关于delphi - 如何使用 Move 连接多个字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33490074/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com