Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 将其他两个字符串之间的所有字符串实例写入日志文件_Delphi_Delphi 10 Seattle - Fatal编程技术网

Delphi 将其他两个字符串之间的所有字符串实例写入日志文件

Delphi 将其他两个字符串之间的所有字符串实例写入日志文件,delphi,delphi-10-seattle,Delphi,Delphi 10 Seattle,在查看并尝试Andreas Rejbrand给出的代码后,我意识到我需要一个不会在一个标记后停止的版本—我的目标是将几个.xml文件中两个字符串之间出现的所有值写入日志文件 <screen> xyz </screen> blah blah <screen> abc </screen> procedure TTagtextextract0r.FormCreate(Sender: TObject); begin Edit2.Text:=(TDi

在查看并尝试Andreas Rejbrand给出的代码后,我意识到我需要一个不会在一个标记后停止的版本—我的目标是将几个.xml文件中两个字符串之间出现的所有值写入日志文件

<screen> xyz </screen> blah blah <screen> abc </screen> 
procedure TTagtextextract0r.FormCreate(Sender: TObject);
begin
  Edit2.Text:=(TDirectory.GetCurrentDirectory);
  AssignFile(LogFile, 'Wordlist.txt');
  ReWrite(LogFile);
  CloseFile(Logfile);
end;
为了得到有问题的文件,我点击一个按钮,然后读取它们

 procedure TTagtextextract0r.Button3Click(Sender: TObject);
 begin
   try
     sD := TDirectory.GetCurrentDirectory;
     Files:= TDirectory.GetFiles(sD, '*.xml');
   except 
     exit
   end;

   j:=Length(Files);
   for k := 0 to j-1 do
   begin
     Listbox2.Items.Add(Files[k]);
     sA:= TFile.ReadAllText(Files[k]);
     iL:= Length(sA);

     AssignFile(LogFile, 'Wordlist.txt');
     Append(LogFile);
     WriteLn(LogFile, (ExtractText('screen', sA)));
     CloseFile (LogFile);
   end;
 end;

 end.

我的问题是,如果函数中没有布尔循环,应用程序只会在每个文件中写入一行,然后停止,但是使用布尔代码,应用程序会陷入无限循环中——但我不太清楚循环没有结束的地方。是不是“WriteLn”命令无法输出函数的结果?如果不能,我不知道如何为函数的每次运行获得一个新行-我在这里做错了什么

首先,您需要掌握调试

请参阅,了解如何暂停和调试失控的程序

另请阅读以了解如何使用断点。如果你已经仔细检查了你的代码,你很快就会发现你错在哪里了

那么你的问题是:

在旧的Delphi版本(直到Delphi XE2)中,您可以使用
PosEx()
函数(如注释中所建议的),这将大大简化
ExtractText()
函数中的代码。从Delphi XE3中,扩展了
System.Pos()
函数,其功能与
PosEx()
相同,即第三个参数
Offset:integer

由于您使用的是Delphi 10西雅图版,因此可以互换使用
System.StrUtils.PosEx()
System.Pos()

System.StrUtils.PosEx

PosEx()返回以S为单位的SubStr索引,从开始搜索 抵消

ExtractText()

函数ExtractText(const标记,text:string):string;
变量
startPos,endPos:整数;
开始
结果:='';
startPos:=1;
重复
startPos:=PosEx(“”,text,startPos)+1;
如果startPos=1,则退出;
endPos:=PosEx(“”,text,startPos);
如果endPos=0,则退出;
结果:=结果+复制(文本、起始位置、结束位置-起始位置)+sLineBreak;
直到错误;
结束;

我在每个找到的文本后添加了
sLineBreak
(在unit
System.Types
),否则它应该按照您的预期工作(我相信)。

学习1)正确缩进代码,以便您可以看到块的开始和停止位置,以及2)学习使用调试器逐步检查代码以查看发生了什么。在本例中,在
ListBox2.Items.Add(Files[k])处设置断点
并使用F8逐步执行代码以执行每一行。(还有一个提示:将
AssignFile
移动到循环开始之前,将
CloseFile
移动到循环结束之后。在循环的每次迭代中重复打开和关闭它是没有意义的。)请注意,您可以使用
PosEx
功能从最后一个位置继续搜索,因此,避免使用
delete
用法。使用xml语法你没有删除文本读取的部分-你正在删除第一个“嗨,伙计们,谢谢你们的支持。”。是的,我现在看到缩进的好处了!(@LU RD感谢您的编辑)我尝试了断点,然后可以将鼠标悬停在变量上,查看分配给它们的值,非常有用。我接受你关于循环中的开始和结束的观点,KW,谢谢。是的,感谢DH,XML解析器是我没有考虑过的一种方法,我必须仔细阅读它!啊,是的,现在也发现了无限循环,谢谢Dsm!谢谢你关于PosEx MBo的留言!在较新的Delphi版本(Unicode)中,相当于
System.StrUtils.PosEx()
@LURD-holy!看来是这样。谢谢,我不知道。我需要重新措辞我的帖子。@LURD我的安装有漏洞。D2010 Pos()无法识别第三个参数。DXE4有。您是否安装了XE、XE2或XE3中的任何一个以检查何时发生更改?从中,似乎XE3是第一个引入偏移量的。我手头没有XE2来检查代码。我今天晚些时候再看。它是XE3的,检查过了。
 procedure TTagtextextract0r.Button3Click(Sender: TObject);
 begin
   try
     sD := TDirectory.GetCurrentDirectory;
     Files:= TDirectory.GetFiles(sD, '*.xml');
   except 
     exit
   end;

   j:=Length(Files);
   for k := 0 to j-1 do
   begin
     Listbox2.Items.Add(Files[k]);
     sA:= TFile.ReadAllText(Files[k]);
     iL:= Length(sA);

     AssignFile(LogFile, 'Wordlist.txt');
     Append(LogFile);
     WriteLn(LogFile, (ExtractText('screen', sA)));
     CloseFile (LogFile);
   end;
 end;

 end.
function PosEx(const SubStr, S: string; Offset: Integer = 1): Integer; inline; overload;
function ExtractText(const tag, text: string): string;
var
  startPos, endPos: integer;
begin
  result := '';
  startPos := 1;

  repeat
    startPos := PosEx('<'+tag, text, startpos);
    if startPos = 0 then exit;
    startPos := PosEx('>', text, startPos)+1;
    if startPos = 1 then exit;

    endPos := PosEx('</'+tag+'>', text, startPos);
    if endPos = 0 then exit;

    result := result + Copy(text, startPos, endPos - startPos) + sLineBreak;
  until false;
end;