Delphi Перебирает текстовый файл для определенной строки, копируя эту строку в переменную

#delphi #text-files

Вопрос:

Таким образом, строка, содержащая «NVMEM», успешно удаляется из текстового файла. На самом деле я хочу, чтобы произошло обратное, когда он удалит каждую строку, кроме строки, содержащей строку «NVMEM». Я попытался изменить оператор if в цикле for кнопки 2 на оператор if, думая, что это сработает, но он просто удаляет все. Есть ли у меня способ удалить все строки, кроме той, которая содержит строковую строку.

 implementation

{$R *.dfm}

procedure TForm3.Button1Click(Sender: TObject);
var
NVE: TextFile;

begin
if not FileExists('NVE.txt') then
  begin
  AssignFile(NVE, 'NVE.txt');
  Rewrite(NVE);

  WriteLn(NVE, 'abcdefg') ;
  WriteLn(NVE, 'hijklmnop')      ;
  WriteLn(NVE, 'fmdiomfsa');
  WriteLn(NVE, 'heres the line with NVMEM'); //line I want to parse


  ShowMessage('You have successfully created the file amigo');
  CloseFile(NVE);

  end;


if FileExists('NVE.txt') then
  begin
    AssignFile(NVE,'NVE.txt');
    Rewrite(NVE);

    WriteLn(NVE, 'abcdefg') ;
    WriteLn(NVE, 'hijklmnop');
    WriteLn(NVE, 'hope i got that right');
    WriteLn(NVE, 'heres the line with NVMEM'); //line I want to parse

      ShowMessage('Eso Final');
      CloseFile(NVE);

  end;
end;

procedure TForm3.Button2Click(Sender: TObject);
var
NVE: string;
i : integer;
raw_data1,stringy: string;
raw_data: TstringList;
begin
  stringy := 'NVMEM';
  i := 0;
  raw_data := TStringlist.Create;
  try
    raw_data.LoadFromFile('NVE.txt');
    for i := raw_data.Count-1 downto 0 do
      if pos(stringy, raw_data[i])<>0 then
        raw_data.Delete(i);
    raw_data.SaveToFile('NVE.txt');
  finally
    raw_data.free;
  end;
end;



end.
 

Комментарии:

1. Там нет if not оператора, но есть not оператор. if not a <> 0 then это то же самое if (not a) <> 0 then , что и, то есть, это проверяет, является ли побитовое отрицание a ненулевым. Это НЕ то же самое, if not (a <> 0) then что проверять, равно ли a нулю. Но, конечно, вы бы написали это как if a = 0 then вместо этого.

2. Вы, вероятно, забыли этот раздел, когда читали документацию сегодня утром!

3. Спасибо вам за ссылку !

4. Что pos() возвращается, если искомая строка найдена, и если она не найдена?

5. @JordonDraggon Не нужно удалять вопросы — вы можете редактировать их. Теперь все предыдущие комментарии исчезли.

Ответ №1:

Сначала вспомните, что function Pos(SubStr, Str: string): integer делает.

 `Pos()` returns the position of `SubStr` within `Str` if `SubStr` is included in `Str`.
`Pos()` returns 0 when `SubStr` is not included in `Str`. 
 

Теперь перейдем к этим строкам кода в Button2Click() (где i индекс строки в raw_data ), которые вы хотите изменить, чтобы удалить все строки, кроме той, которая содержит «NVMEM».:

   if pos(stringy, raw_data[i]) <> 0 then  // your current code
    raw_data.Delete(i);
 

Который может быть сформулирован как «если stringy включен в raw_data[i], затем удалите raw_data[i]» и который противоположен тому, что вы хотите.

Чтобы изменить логику, то есть «если stringy не включен в raw_data[i], затем удалите raw_data[i]», сделайте следующее:

Pos() возвращает 0 , если SubStr не включено Str , следовательно, условием для удаления строки должно быть:

   if pos(stringy, raw_data[i]) = 0 then   // change `<>` to `=`
    raw_data.Delete(i);
 

В результате у вас останется одна строка в raw_data: TStringList строке , содержащей «NVMEM».