写一个函数参数为两个数组: function GetArrFromArr(SourArr,NewArr:array of byte):integer; 在其中用 for do + if then 查出NewArr在SourArr中的位置,然后返回,这样就是通用了,换别的数组也可以了 如果还想对其他类型也适用可以重载一下
function SearchBuffer(Buffer: array of Byte; SubBuffer: array of Byte; iStart: Integer = 0): Integer; var iIndex : Integer; iLoop : Integer; bFind : Boolean; begin Result := -1; for iIndex := Low(Buffer) + iStart to High(Buffer) - Length(SubBuffer) + 1 do begin bFind := True; for iLoop := Low(SubBuffer) to High(SubBuffer) do if Buffer[iIndex + iLoop - Low(SubBuffer)] <> SubBuffer[iLoop] then begin bFind := False; break; end; if bFind then begin Result := iIndex; break; end; end; end;procedure TForm1.Button1Click(Sender: TObject); var Buffer: array [0..255] of byte; SubBuf: array [0..3] of Byte; iLoop : Integer; iPos : Integer; begin for iLoop := Low(buffer) to High(buffer) do Buffer[iLoop] := iLoop; SubBuf[0] := 10; SubBuf[1] := 11; SubBuf[2] := 12; SubBuf[3] := 13; iPos := SearchBuffer(Buffer, SubBuf); if iPos <> -1 then begin ShowMessage (Format('Found at pos %d', [iPos])); //Search again iPos := SearchBuffer(Buffer, Buf, iPos + 1); if iPos <> -1 then ShowMessage (Format('Found at pos %d', [iPos])) else ShowMessage ('Not found'); end else ShowMessage ('Not found'); end;
我有一种思路,只不过,临时看来,数组元素不能有 $FF 这个值。当然,这个问题仔细想想也是可以解决的。我的思路如下:type TMyByteArr = Array[0..255] of Byte;function MySearch(var Buff : TMyByteArr; SubBuff : String) : integer; var I : integer; begin for I := Low(Buff) to High(Buff) do Buff[I] := Buff[I] +1; Result := Pos(SubBuff, StrPas(@Buff[Low(Buff)])); for I := Low(Buff) to High(Buff) do Buff[I] := Buff[I] -1; end;procedure TForm1.Button1Click(Sender: TObject);//测试一下 var buffer : TMyByteArr; Found : integer; SubStr : string; begin Buffer[2] := $13; Buffer[3] := $0; Buffer[4] := $10; Buffer[5] := $0; Buffer[6] := $13; SubStr := Chr($14)+Chr($1)+Chr($11)+Chr($1);//注意,每个Byte要加1。这不难。 Found := MySearch(Buffer, SubStr); showmessage(IntToStr(Found)); end;
汗.......!!!!找到一个函数:CompareMem,直接用就行了!(我前面的一种思路实际上就是这种思路:内存块比较,如今找到这个函数了,就不用那么费事了。)procedure TForm1.Button1Click(Sender: TObject); var buffer : Array[0..255] of Byte; SubBuf : Array[0..3] of Byte; I : integer; begin fillChar(Buffer, 256, 0);//下面搞几个数据测试 Buffer[2] := $13; Buffer[3] := $0; Buffer[4] := $10; Buffer[5] := $0; Buffer[6] := $18; SubBuf[0] := $13;//这是要查找的连续元素,放在SubBuf里。 SubBuf[1] := $0; SubBuf[2] := $10; SubBuf[3] := $0; for I := Low(Buffer) to High(Buffer) do if SysUtils.CompareMem(@Buffer[I], @SubBuf[0], SizeOf(SubBuf)) then ShowMessage('找到一段,起始处位于第' + inttostr(I) + '号元素'); end;上面我用了定长数组。可以用动态数组的。
上面的调用,有一点点需要改正的地方:(下面是改正后) for I := Low(Buffer) to High(Buffer)-SizeOf(SubBuf)+1 do if SysUtils.CompareMem(@Buffer[I], @SubBuf[Low(SubBuf)], SizeOf(SubBuf)) then ShowMessage(Format('找到一段,起始处位于%d号元素',[I])); 楼主及上面各位朋友,试一下 CompareMem 吧!其实就是 C/C++ 里的 memcmp 函数。实在是好用啊,直接对内存块进行比较。
根据楼上几位意见写的,大家看看还有什么需要改进 function PosMemEx(subBuf, Buf : array of byte; Offset: Cardinal = 0):Integer; var bFind : Boolean; I : Integer; begin Result:=-1; bFind:=False; for I := Low(Buf) + Integer(Offset) to High(Buf)-SizeOf(SubBuf)+1 do if SysUtils.CompareMem(@Buf[I], @SubBuf[Low(SubBuf)], SizeOf(SubBuf)) then begin bFind:=true; break; end; if bFind then Result:=I; end;
function PosMemEx(subBuf, Buf : array of byte; Offset: Cardinal = 0):Integer; var I : Integer; begin Result:=-1; for I := Low(Buf) + Integer(Offset) to High(Buf)-SizeOf(SubBuf)+1 do if SysUtils.CompareMem(@Buf[I], @SubBuf[Low(SubBuf)], SizeOf(SubBuf)) then begin Result:=I; break; end; end;
function GetArrFromArr(SourArr,NewArr:array of byte):integer;
在其中用 for do + if then 查出NewArr在SourArr中的位置,然后返回,这样就是通用了,换别的数组也可以了
如果还想对其他类型也适用可以重载一下
var
iIndex : Integer;
iLoop : Integer;
bFind : Boolean;
begin
Result := -1;
for iIndex := Low(Buffer) + iStart to High(Buffer) - Length(SubBuffer) + 1 do
begin
bFind := True;
for iLoop := Low(SubBuffer) to High(SubBuffer) do
if Buffer[iIndex + iLoop - Low(SubBuffer)] <> SubBuffer[iLoop] then
begin
bFind := False;
break;
end;
if bFind then
begin
Result := iIndex;
break;
end;
end;
end;procedure TForm1.Button1Click(Sender: TObject);
var
Buffer: array [0..255] of byte;
SubBuf: array [0..3] of Byte;
iLoop : Integer;
iPos : Integer;
begin
for iLoop := Low(buffer) to High(buffer) do Buffer[iLoop] := iLoop;
SubBuf[0] := 10;
SubBuf[1] := 11;
SubBuf[2] := 12;
SubBuf[3] := 13;
iPos := SearchBuffer(Buffer, SubBuf);
if iPos <> -1 then
begin
ShowMessage (Format('Found at pos %d', [iPos]));
//Search again
iPos := SearchBuffer(Buffer, Buf, iPos + 1);
if iPos <> -1 then
ShowMessage (Format('Found at pos %d', [iPos]))
else
ShowMessage ('Not found');
end
else
ShowMessage ('Not found');
end;
TMyByteArr = Array[0..255] of Byte;function MySearch(var Buff : TMyByteArr; SubBuff : String) : integer;
var
I : integer;
begin
for I := Low(Buff) to High(Buff) do
Buff[I] := Buff[I] +1;
Result := Pos(SubBuff, StrPas(@Buff[Low(Buff)]));
for I := Low(Buff) to High(Buff) do
Buff[I] := Buff[I] -1;
end;procedure TForm1.Button1Click(Sender: TObject);//测试一下
var
buffer : TMyByteArr;
Found : integer;
SubStr : string;
begin
Buffer[2] := $13;
Buffer[3] := $0;
Buffer[4] := $10;
Buffer[5] := $0;
Buffer[6] := $13;
SubStr := Chr($14)+Chr($1)+Chr($11)+Chr($1);//注意,每个Byte要加1。这不难。
Found := MySearch(Buffer, SubStr);
showmessage(IntToStr(Found));
end;
jadeluo(秀峰) 可以用
再看看大家有什么想法
下午结帖
var
buffer : Array[0..255] of Byte;
I : integer;
SubStr : integer;
P : ^integer;
begin
fillChar(Buffer, 256, 0);
Buffer[2] := $13;
Buffer[3] := $0;
Buffer[4] := $10;
Buffer[5] := $0;
Buffer[6] := $13;
SubStr := ($13 shl 24) + ($0 shl 16) + ($10 shl 8) + ($0);
//SubStr := $13001000; //或者这样写
for I := Low(Buffer) to High(Buffer)-3 do
begin
P := @Buffer[I];
if P^ = SubStr then showmessage(IntToStr(I));
end;
end;
SubStr := ($13) + ($0 shl 8) + ($10 shl 16) + ($0 shl 24);
//SubStr := $00100013; //或者这样写
var
buffer : Array[0..255] of Byte;
SubBuf : Array[0..3] of Byte;
I : integer;
begin
fillChar(Buffer, 256, 0);//下面搞几个数据测试
Buffer[2] := $13;
Buffer[3] := $0;
Buffer[4] := $10;
Buffer[5] := $0;
Buffer[6] := $18; SubBuf[0] := $13;//这是要查找的连续元素,放在SubBuf里。
SubBuf[1] := $0;
SubBuf[2] := $10;
SubBuf[3] := $0;
for I := Low(Buffer) to High(Buffer) do
if SysUtils.CompareMem(@Buffer[I], @SubBuf[0], SizeOf(SubBuf)) then
ShowMessage('找到一段,起始处位于第' + inttostr(I) + '号元素');
end;上面我用了定长数组。可以用动态数组的。
if SysUtils.CompareMem(@Buffer[I], @SubBuf[Low(SubBuf)], SizeOf(SubBuf)) then
ShowMessage(Format('找到一段,起始处位于%d号元素',[I]));
楼主及上面各位朋友,试一下 CompareMem 吧!其实就是 C/C++ 里的 memcmp 函数。实在是好用啊,直接对内存块进行比较。
function PosMemEx(subBuf, Buf : array of byte; Offset: Cardinal = 0):Integer;
var
bFind : Boolean;
I : Integer;
begin
Result:=-1;
bFind:=False;
for I := Low(Buf) + Integer(Offset) to High(Buf)-SizeOf(SubBuf)+1 do
if SysUtils.CompareMem(@Buf[I], @SubBuf[Low(SubBuf)], SizeOf(SubBuf)) then
begin
bFind:=true;
break;
end;
if bFind then Result:=I;
end;
var
I : Integer;
begin
Result:=-1;
for I := Low(Buf) + Integer(Offset) to High(Buf)-SizeOf(SubBuf)+1 do
if SysUtils.CompareMem(@Buf[I], @SubBuf[Low(SubBuf)], SizeOf(SubBuf)) then
begin
Result:=I;
break;
end;
end;