利用Tstringlist删除文件中有‘                            4  1’,‘RINEX FILE SPLICE; other post-header comments skipped       COMMENT’的行,空白处为空格符。
代码如下:
procedure TForm1.Button2Click(Sender: TObject);
var
s:tstrings;
num,pos1,pos2:integer;
begin
  s:=tstringlist.create;
  s.loadfromfile('c:\usno.06o');
  for num:=0 to s.count-1 do
  begin
   pos1:=pos('                            4  1',s[num]);
   pos2:=pos('RINEX FILE SPLICE; other post-header comments skipped              COMMENT',s[num]);
   if pos1>0    then
     s.Delete(num);
   if pos2>0 then
     s.Delete(num); 
     s.SaveToFile('c:\1.06o');
   end;
 end;
在执行中出错提示'list index out of bounds (48410)',此文件一共48432行。
本以为是超出了列表行数,但不作删除操作,把这些内容放在memo里都能正常显示出来,所以觉得还不是超出原因,可以是出在删除操作上了,请大家帮我看看是哪里出错,另外觉得这种方法操作文件有点慢,有没有什么好的方法,大家指点一下,万分感谢。。

解决方案 »

  1.   

    还想问一下,为什么不能把上面定位到要删除行的代码改为如下代码:
     if pos1>0 or pos2>0 then
      s.delete(num);
    在这样写的时候总是编译不过,不知道是为什么。。
      

  2.   

    for num:=0 to s.count-1 do
        ~~~~~~~~~~~~~~~~~~~
    类似 这样在List类里删除某行的循环,一般要用DownTo处理:for num := s.count-1 to 0 do ...
      

  3.   

    打错了,改正:for num := s.count-1 DownTo 0 do ...
      

  4.   

    还有几个需要注意的地方:1、s.SaveToFile('c:\1.06o');这句放在循环外面执行即可。2、TStringList对象 s 既然Create了,就要记得释放:s.Free;全部改写后的代码如下:var
      s : TStringList ;
      num,pos1,pos2 : integer;
    begin
      s := TStringList.Create;
      s.Loadfromfile('c:\usno.06o');
      for num := s.count-1 DownTo 0 do
          begin
          pos1:=pos('                            4  1',s[num]);
          pos2:=pos('RINEX FILE SPLICE; other post-header comments skipped              COMMENT',s[num]);
          if pos1>0 then  s.Delete(num);
          if pos2>0 then  s.Delete(num);
          end;
      s.SaveToFile('c:\1.06o');
      s.Free;
    end;
      

  5.   

    var
      s : TStringList ;
    begin
      s := TStringList.Create;
      s.Loadfromfile('c:\usno.06o');
      StringReplace(s.text,'                            4  1','',[rfReplaceAll]);
      StringReplace(s.text,'FILE SPLICE; other post-header comments skipped              COMMENT','',[rfReplaceAll]);
      s.SaveToFile('c:\1.06o');
      s.Free;
    end;
      

  6.   

    昨晚连回三次,CSDN不让超过三次...呵呵还想问一下,为什么不能把上面定位到要删除行的代码改为如下代码:
     if pos1>0 or pos2>0 then
      s.delete(num);
    在这样写的时候总是编译不过,不知道是为什么。。
    ------------------------------------------------
    因为 > 的优先级要低于 or 运算,所以,改成这样就可以:
     if (pos1>0) or (pos2>0) then
      s.delete(num);
      

  7.   

    if (pos1>0) or (pos2>0) then
      

  8.   

    主要问题是出在循环遍历用downto,就是从s.count-1 开始 到0, 这样才不会出现下标溢出的问题!
      

  9.   

    wywry的方法,也算一种方法,但是,虽然看起来代码短小, 在处理这个具体问题时, 并不太实用.
    况且wywry的方法需要改一下: (添加s.text := 部分)
    var
      s : TStringList ;
    begin
      s := TStringList.Create;
      s.Loadfromfile('c:\usno.06o');
      s.text := StringReplace(s.text,'                            4  1','',[rfReplaceAll]);
      s.text := StringReplace(s.text,'FILE SPLICE; other post-header comments skipped              COMMENT','',[rfReplaceAll]);
      s.SaveToFile('c:\1.06o');
      s.Free;
    end;{ 删除相应的子串,但没有删除该行(保留空行) }参考:http://community.csdn.net/Expert/topic/5253/5253038.xml?temp=4.920596E-02
      

  10.   

    接着我在楼上的楼上所说的说:用StringReplace也是可以去掉空行的,比如,这样:(在判断的子串里,加上回车符和换行符#13#10)var
      s : TStringList ;
    begin
      s := TStringList.Create;
      s.Loadfromfile('c:\usno.06o');
      s.text := StringReplace(s.text,'                            4  1'+#13+#10,'',[rfReplaceAll]);
      s.text := StringReplace(s.text,'FILE SPLICE; other post-header comments skipped              COMMENT'+#13+#10,'',[rfReplaceAll]);
      s.SaveToFile('c:\1.06o');
      s.Free;
    end;{ 但总是感觉不踏实,因为,有这种可能:只有换行符,没有回车符 }
      

  11.   

    谢谢大家的回复,从中学到了不少Tstringlist的知识,我还是刚接解DELPHI,以后还请大家多多关照!