大家好,
我在PHP中有一个小代码,我想在Delphi中转换,我有一些麻烦...
这是PHP代码:
$from = "121.198.0.0";
$to = "121.198.255.255";
$arry1 = explode(".", $from);
$arry2 = explode(".", $to);
$a1 = $arry1[0];
$b1 = $arry1[1];
$c1 = $arry1[2];
$d1 = $arry1[3];
$a2 = $arry2[0];
$b2 = $arry2[1];
$c2 = $arry2[2];
$d2 = $arry2[3];
while ($d2 >= $d1 || $c2 > $c1 || $b2 > $b1 || $a2 > $a1) {
if ($d1 > 255) {
$d1 = 1;
$c1++;
}
if ($c1 > 255) {
$c1 = 1;
$b1++;
}
if ($b1 > 255) {
$b1 = 1;
$a1++;
}
echo "$a1.$b1.$c1.$d1<br>";
$d1++;
}
在Delphi中我开始说:
procedure TForm1.Button1Click(Sender: TObject);
var
Arry1, Arry2: TStringList;
RangeFrom, RangeTo: string;
a1, b1, c1, d1, a2, b2, c2, d2: string;
begin
RangeFrom := Edit1.Text;
RangeTo := Edit2.Text;
Arry1 := Explode('.', RangeFrom);
Arry2 := Explode('.', RangeTo);
a1 := Arry1[0];
b1 := Arry1[1];
c1 := Arry1[2];
d1 := Arry1[3];
a2 := Arry1[0];
b2 := Arry1[1];
c2 := Arry1[2];
d2 := Arry1[3];
while (StrToInt(d2) >= StrToInt(d1))
//and StrToInt(c2) > (StrToInt(c1)
//and StrToInt(b2) > (StrToInt(b1)
//and StrToInt(a2) > (StrToInt(a1)
do
begin
if (StrToInt(d1) > 255) then
begin
d1 := '1';
StrToInt(c1)+1;
end;
if (StrToInt(c1) > 255) then
begin
c1 := '1';
StrToInt(b1)+1;
end;
if (StrToInt(b1) > 255) then
begin
b1 := '1';
StrToInt(a1)+1;
end;
ListBox1.Items.Add(a1+'.'+b1+'.'+c1+'.'+d1);
StrToInt(d1)+1;
end;
end;
(对于爆炸功能,我使用:http://www.marcosdellantonio.net/2007/06/14/funcao-explode-do-php-em-delphi/)
有人可以帮我在Delphi中编写这个小代码吗?
提前致谢:)
贝尼
答案 0 :(得分:6)
通过查看代码,我可以看到以下内容:
如果您认为参数{_ 1}}的顺序错误。分隔符是您链接的函数中的第二个参数。所以你应该写:
Explode
您正在通过不释放Arry1 := Explode(RangeFrom, '.');
Arry2 := Explode(RangeTo, '.');
函数返回的数组来泄漏内存。 Delphi与PHP的不同之处在于您经常需要管理您创建的对象的内存。
Explode
这些应该是a2 := Arry1[0];
b2 := Arry1[1];
c2 := Arry1[2];
d2 := Arry1[3];
而不是Arry2
。
您应该先将字符串转换为整数。所以声明他们是这样的:
Arry1
并写下这样的作业:
a1, b1, c1, d1, a2, b2, c2, d2: Integer;
a1 := StrToInt(Arry1[0]);
b1 := StrToInt(Arry1[1]);
//etc. etc.
转换为:
while ($d2 >= $d1 || $c2 > $c1 || $b2 > $b1 || $a2 > $a1)
在while循环中你需要这样的代码:
while ((d2 >= d1) or (c2 > c1) or (b2 > b1) or (a2 > a1))
使用if d1 > 255 then
begin
d1 := 1;
inc(c1);
end;
函数将4个值转换回IP地址最简单:
Format
你误解了ListBox1.Items.Add(Format('%d.%d.%d.%d', [a1, b1, c1, d1]));
这是一个函数,它接收一个字符串作为输入并返回一个整数。当你写:
StrToInt
您没有修改变量StrToInt(d1)+1
,它只是一个输入变量。当您进行我描述的其他更改时,该问题就会消失,但我想指出它以便您将来获益。
您可能还想强制定期重新绘制列表框,以便查看正在发生的事情。
把它们放在一起就可以了:
d1
答案 1 :(得分:0)
我认为它现在没有做任何事情的原因是你在edit1.text或edit2.text中可能没有任何值。
为了测试(在使这个片段成为一个过程或函数之前),您可以将一些测试数据分配给RangeFrom和RangeTo。
实施例。 RangeFrom:='121.198.0.0'; RangeTo:='121.198.255.255';
答案 2 :(得分:0)
测试目标:
procedure TForm1.Button1Click(Sender: TObject);
var
AddrList: TStringList;
StartAddress,
EndAddress: Cardinal;
a, b, c, d: PByte;
x: Cardinal;
begin
AddrList := TStringList.Create;
AddrList.Delimiter := '.';
AddrList.DelimitedText := Edit1.Text;
StartAddress := (Cardinal(StrToInt(AddrList.Strings[0])) shl 24 ) +
(Cardinal(StrToInt(AddrList.Strings[1])) shl 16) +
(Cardinal(StrToInt(AddrList.Strings[2])) shl 8) +
StrToInt(AddrList.Strings[3]);
AddrList.DelimitedText := Edit2.Text;
EndAddress := (Cardinal(StrToInt(AddrList.Strings[0])) shl 24 ) +
(Cardinal(StrToInt(AddrList.Strings[1])) shl 16) +
(Cardinal(StrToInt(AddrList.Strings[2])) shl 8) +
StrToInt(AddrList.Strings[3]);
AddrList.Free;
for x := StartAddress to EndAddress do begin
a := @x;
b := a;
Inc(a);
c := a;
Inc(a);
d := a;
Inc(a);
Memo1.Lines.Add(Format('%d.%d.%d.%d', [a^,d^,c^,b^]));
end;
end;