举一个例子,假设我想写一个简单的程序来删除' X'字符串中的字符。
如何设计我的程序,使其适用于字符串和PCHAR参数。
如果我将其定义为:
程序RemoveX(来源:PCHAR);
调用RemoveX(PCHAR(mystring)),其中myString是一个字符串将删除' X'但不会照顾更新字符串长度...因此后续的myString:= myString +' done'将保持myString不变。在调用RemoveX之后我不想改变长度,我希望RemoveX程序可以处理所有内容。
如果另一方面我将其定义为:
程序RemoveX(var source:string);
我不知道怎么把它传给PCHAR ......
答案 0 :(得分:5)
我不建议根据string
版本实施PChar
版本,反之亦然。我会将它们分开,以便您可以独立定制它们,例如:
procedure RemoveX(source : PChar); overload;
procedure RemoveX(var source : string); overload;
procedure RemoveX(source : PChar);
var
P: PChar;
Len: Integer;
begin
if source = nil then Exit;
Len := StrLen(source);
repeat
P := StrScan(source, 'X');
if P = nil then Exit;
StrMove(P, P+1, Len - Integer(P-source));
Dec(Len);
source := P;
until False;
end;
procedure RemoveX(var source : string);
begin
source := StringReplace(source, 'X', '', [rfReplaceAll]);
end;
更新:如果您真的想对PChar
和String
输入使用单一实现,那么您可以执行以下操作:
function RemoveX(source : PChar; sourceLen: Integer): Integer; overload;
procedure RemoveX(source : PChar); overload;
procedure RemoveX(var source : string); overload;
function RemoveX(source : PChar; sourceLen: Integer): Integer;
var
P: PChar;
begin
Result := 0;
if (source = nil) or (sourceLen = 0) then Exit;
repeat
P := StrScan(source, 'X');
if P = nil then Exit;
StrMove(P, P+1, sourceLen - Integer(P-source));
Dec(sourceLen);
source := P;
until False;
Result := sourceLen;
end;
procedure RemoveX(source : PChar);
begin
RemoveX(source, StrLen(source));
end;
procedure RemoveX(var source : string);
begin
UniqueString(source);
SetLength(source, RemoveX(PChar(source), Length(source)));
end;
答案 1 :(得分:2)
您无法使用单个参数实现此功能。你有两种不同的类型。
您可以在PChar
版本之上构建字符串版本。
procedure RemoveX(var str: string);
var
P: PChar;
begin
UniqueString(str);
P := PChar(str);
RemoveX(P);
str := P;
end;
最后一行的替代方案可能是:
SetLength(str, StrLen(P));
无论哪种方式,这显然都假设您已经在PChar
上运行了一个正常运行的重载。并且该函数删除了字符。显然它无法扩展PChar
缓冲区。
如果共享字符串(引用计数大于1)或常量,则需要调用UniqueString
。在此调用之后,字符串缓冲区是可编辑的,不会被共享。
是否以这种方式避免重复实施是我不能说的最佳方法。这取决于您的设计驱动程序。如果代码的简单性和清晰度是关键,那么避免重复是有道理的。如果性能是关键,则可能需要提供两个定制实现。