We help IT Professionals succeed at work.

Check out our new AWS podcast with Certified Expert, Phil Phillips! Listen to "How to Execute a Seamless AWS Migration" on EE or on your favorite podcast platform. Listen Now

x

Newbie Alert - Working with strings and files

EE_Newguy
EE_Newguy asked
on
Medium Priority
177 Views
Last Modified: 2010-04-05
As the title suggest I am new to delphi or programming in general (only been doing it for like 2 weeks now) so please bear with me as I do my best to explain my questions.

I need to write some text from a memo to a text file like this.

Starting Point: memo text here :Ending Point

where "Starting Point:" is the text from an edit box and ":Ending Point" is the literal phrase ":Ending Point"

In the file I will have lots of different blocks like the one above  but each should begin with "Starting Point:" and end with ":Ending Point" so my first question is if there is an easy/efficent way to do this ?

My next question is now that I have all those blocks in the text file how can I extract just one of them from the file and show it back on my memo ?

And finally how can I delete one of the above blocks including the Starting Point: and :Ending Point stuff.

I hope 200 points is enough for this question because it's all I have left :)
Comment
Watch Question

Commented:
I understood the part of your question and will answer to this part. You can load file into Memo component using following code:

Memo1.Lines.LoadFromFile(FileName);

Hope it will help you
Regards Ferhad

Commented:
I will tell you what i have understood from your question. You want to add some text from some EditBox into file than insert text of Memo component to this text file and finally to insert text of another EditBox to this file. The text of Memo will be in center. The text of Edit1 at the top and the text of Edit2 at bottom. If i am wrong explain me a little bit what you exactly want.
If each block starts with "Starting Point:" and ends with "Ending Point:" then you have nothing that is unique to search for when attempting to extract a certain block. Unless of course they were uniquely identified. Expecially if your looking for a particular block. If you want all those blocks, then its not a problem. However, wanting one particular block out of them all, it becomes a problem of identifying the block. If they were uniquely identified,

Example:

"Starting Point 1"

<Some Text>

 "Ending Point 1"

OR

"1 Starting Point"

<Some Text>

 "1 Ending Point "

OR

"Starting Point A"

<Some Text>

 "Ending Point A"

An other way would be if you knew the exact Start Line number and End Line number of the block of text in the memo.

Example: Deleting the block

For I:= EndLine downto StartLine
 Memo1.Lines.Delete(I);


Example: extracting the block

MyBlock: TStringList.Create;

For I:= StartLine to EndLine do
 MyBlock.Lines.Add(Memo1.Lines[I]);


Hope this helps!

SHane

Commented:
Here is one of the possible solutions.
Procedure ReadMemo reads selected block from a file

unit Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  procedure ReadMemo(Desired: integer);
  public
    { Public declarations }
  end;

const
  START_TXT = 'Starting Point:';
  END_TXT = ':Ending Point';
var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  F: TextFile;
  I: integer;
begin
  AssignFile(F,'file.txt');
  if FileExists('file.txt') then
    Append(F)
  else
    Rewrite(F);

  Writeln(F,START_TXT);
  for I := 0 to Memo1.Lines.Count-1 do
    Writeln(F,Memo1.Lines[I]);
  Writeln(F,END_TXT);

  CloseFile(F);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  ReadMemo(2);  // for example 2 block - must be something wiser
end;

procedure TForm1.ReadMemo(Desired: integer);
var
  F: TextFile;
  I: integer;
  str: string;
begin
  if FileExists('file.txt') then
    begin
    AssignFile(F,'file.txt');
    FileMode := 0;
    Reset(F);

    I := 0;
    while not Eof(F) do
      begin
      Readln(F,str);
      if str = START_TXT then
        begin
        Inc(I);
        if I = Desired then
          break;
        end;
      end;
    Memo1.Clear;
    while not Eof(F) do
      begin
      Readln(F,str);
      if str <> END_TXT then
        Memo1.Lines.Add(str)
      else
        break;
      end;

    CloseFile(F);
    end;
end;

end.

Author

Commented:
=====================================
To ferhad
=====================================

You pretty much understand what I am getting at except the last edit box will not be need because I will be using the contstant ":Ending Point" for the last part.


=====================================
To shaneholmes
=====================================

 I think you missed this part of what I said above so I will repost it here.

where "Starting Point:" is the text from an edit box and ":Ending Point" is the literal phrase ":Ending Point"

So as you can "Starting Point:" is not what it will be in the file but I had to put it in the example to show the layout of the blocks. Maybe it would have been better to say it like this "Edit1.Text:" memo text ":Ending Point"


===================================
To mokule
===================================

 Haven't tried your solution yet but I think you also missed the part where I will be using the text from an edit box as the "Starting Point:" value. Like I said to shaneholmes I only put "Starting Point:" to show the layout of the blocks.
Commented:
Unlock this solution with a free trial preview.
(No credit card required)
Get Preview
Unlock this solution with a free trial preview.
(No credit card required)
Get Preview
TO delete, do the following

For I:= EndLine Downto StartLine do
Memo1.Lines.Delete(I);

Shane

Author

Commented:
Thank you all for your comments I will let you all know how it goes after I wake up cuz right now I am exhausted and need sleep

Commented:
Hi,

My version (not fully tested):

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Memo1: TMemo;
    btnLoad: TButton;
    btnSave: TButton;
    btnDelete: TButton;
    procedure btnLoadClick(Sender: TObject);
    procedure btnSaveClick(Sender: TObject);
    procedure btnDeleteClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

const
  Filename = 'c:\memos.txt';
  MemoEnd = ':Ending Point';

var
  sl: TStringList;

function DeleteBlock(title: string): boolean;
var
  i, k: integer;
  s: string;
begin
  result := true;
  try
    sl.LoadFromFile(Filename);
    i := Pos(title, sl.Text);
    if i > 0 then begin
      s := Copy(sl.Text,1, i -1);
      sl.Text := Copy(sl.Text, i, Length(sl.Text));
      k := Pos(MemoEnd, sl.Text);
      if k > 0 then begin
        s := s + Copy(sl.Text, k + 13, Length(sl.Text));
        sl.Text := s;
        sl.SaveToFile(Filename);
      end;
    end;
  except
    result := false;
  end;
end;

function ReadBlock(title: string; body: TStrings): boolean;
var
  i: integer;
begin
  result := true;
  try
    body.Clear;
    sl.LoadFromFile(Filename);
    i := Pos(title, sl.Text);
    if i > 0 then begin
      body.Text := Copy(sl.Text, i, Length(sl.Text));
      i := Pos(MemoEnd, body.Text);
      if i > 0 then begin
        body.Text := Copy(body.Text, 1, i + 12);
      end;
    end;
  except
    result := false;
  end;
end;

function WriteBlock(title: string; body: TStrings): boolean;
var
  i: integer;
begin
  result := true;
  try
    // delete the block first
    if FileExists(Filename) then begin
      sl.LoadFromFile(Filename);
      i := Pos(title, sl.Text);
      if i > 0 then begin
        DeleteBlock(title);
        sl.LoadFromFile(Filename);
      end;
    end;
    sl.Add(title);
    sl.Add(body.Text);
    sl.Add(MemoEnd);
    sl.SaveToFile(Filename);
  except
    result := false;
  end;
end;

procedure TForm1.btnLoadClick(Sender: TObject);
begin
  if not ReadBlock(Edit1.Text, Memo1.Lines) then
    ShowMessage('Error reading the block');
end;

procedure TForm1.btnSaveClick(Sender: TObject);
begin
  if not WriteBlock(Edit1.Text, Memo1.Lines) then
    ShowMessage('Error writing the block');
end;

procedure TForm1.btnDeleteClick(Sender: TObject);
begin
  if not DeleteBlock(Edit1.Text) then
    ShowMessage('Error deleting the block');
end;

initialization
  sl := TStringList.Create;

finalization
  sl.Free;

end.

Regards, Geo

Author

Commented:
Thanks Geo for your comments and your solution is the most complete of the three and would work great except one thing.

when reading the text back into the memo I want to remove the "Starting Point:" and ":Ending Point" phrases so what do I need to do to remove them or better yet not include them in the first place.

In other words if I have in the file a block that goes like this.

Everybody: eat your dinner :Ending Point

all I want to read back to the memo is "eat your dinner" not the Everybody: and :Ending Point stuff.

Author

Commented:
Geo
=====================================

 I know you said your comment was not fully tested so I just thought I would point out a couple of bugs I found.

If I add an block with the title of "test3" and then add another one with the title of "test33" and  if i put "test3" into the edit box and press the delete button it will delete "test3" (which it's supposed to do) but if i press the delete button again it will delete "test33" as well (which it should not do)

The same thing goes for loading... If i delete "test3" and press the load button it will load "test33" even though "test3" is in the edit box

Finally If I save a title of "gone fishing" to the file and then delete the file and save the title "gone fishing" again it adds it twice to the file. Thank you for your time.

======================================


Shaneholmes
======================================
 Where do I put the last code(s) you posted and not sure but I don't see anything about the reading of the text back to the memo. Thank you for your time



======================================
mokule

 Your code would also work I think but the ReadMemo Procedure needs to be changed so it will work with the edit1.text instead of a number and not sure but I did not see a method to delete a block so if you can add that as well it would be great. Thank you for your time.
Commented:
Unlock this solution with a free trial preview.
(No credit card required)
Get Preview
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a free trial preview!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.