-2

举个例子,假设我想编写一个简单的过程,从字符串中删除“X”字符。

我如何设计我的程序,以便它适用于字符串和 PCHAR 参数。

如果我将其定义为:

过程 RemoveX(来源:PCHAR);

比调用 RemoveX(PCHAR(mystring)) (其中 myString 是一个字符串)将删除 'X' 但不会更新字符串长度......因此后续的 myString := myString + 'done' 将使 myString 保持不变。而且我不想在调用 RemoveX 后更改长度,我希望 RemoveX 过程能够处理所有事情。

另一方面,如果我将其定义为:

过程 RemoveX( var source : string);

我不知道如何将其传递给 PCHAR ...

4

2 回答 2

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;
于 2014-11-05T17:56:09.850 回答
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缓冲区。

UniqueString如果字符串是共享的(引用计数大于一)或常量,则需要调用 to 。在此调用之后,字符串缓冲区可编辑且不可共享。

我不能说是否以这种方式避免重复实施是最好的方法。这取决于您的设计驱动程序。如果代码的简单性和清晰性是关键,那么避免重复是有意义的。如果性能是关键,那么可能需要提供两个定制的实现。

于 2014-11-05T13:27:22.317 回答