首页 > 解决方案 > 如何修改 AnsiStrPos 函数以返回整数偏移量?(德尔福 7)

问题描述

我正在使用 Delphi 7,我想要类似于 ansipos 的函数,但它应该使用输入偏移量参数并返回整数偏移量。我在这里找到了与此类似的代码https://github.com/Fr0sT-Brutal/Delphi_MiniRTL/blob/master/SysUtils.pas我想将输出修改为整数偏移量。如何从 PChar 获取整数偏移量?

function AnsiStrPos(Str, SubStr: PChar): PChar;
var
  L1, L2: Cardinal;
  ByteType : TMbcsByteType;
begin
  Result := nil;
  if (Str = nil) or (Str^ = #0) or (SubStr = nil) or (SubStr^ = #0) then Exit;
  L1 := StrLen(Str);
  L2 := StrLen(SubStr);
  Result := StrPos(Str, SubStr);
  while (Result <> nil) and ((L1 - Cardinal(Result - Str)) >= L2) do
  begin
    ByteType := StrByteType(Str, Integer(Result-Str));
    if (ByteType <> mbTrailByte) and
      (AnsiCompareStr(Result, SubStr) = 0) then Exit;
    if (ByteType = mbLeadByte) then Inc(Result);
    Inc(Result);
    Result := StrPos(Result, SubStr);
  end;
  Result := nil;
end;

例如 str := "sub_string"; 从“sub_string”我想找到“string”,从位置4开始搜索,结果应该是0。

标签: stringdelphipointers

解决方案


试试这个解决方案:

function AnsiStrOffset(AStr, ASubStr: PChar; const AStartPos: Cardinal = 0): Integer;
var
  VPos: PChar;
begin
  Result := -1; // not found
  if StrLen(AStr) <= AStartPos then begin
    Exit;
  end;
  Inc(AStr, AStartPos);
  VPos := AnsiStrPos(AStr, ASubStr);
  if VPos <> nil then begin
    Result := Int64(VPos) - Int64(AStr);
    // add AStartPos to Result if you need offset from the string beginning
  end;
end;

用法:

var
  VOffs: Integer;
  VStr, VSubStr: string;
begin
  VStr := 'sub_string';
  VSubStr := 'string';

  VOffs := AnsiStrOffset(PChar(VStr), PChar(VSubStr), 4);

  WriteLn(VOffs); // prints 0
end;

推荐阅读