Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 150
  • Last Modified:

Newbie Alert - Working with strings and files

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 :)
0
EE_Newguy
Asked:
EE_Newguy
  • 4
  • 3
  • 2
  • +2
3 Solutions
 
ferhadCommented:
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
0
 
ferhadCommented:
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.
0
 
shaneholmesCommented:
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
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
mokuleCommented:
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.
0
 
EE_NewguyAuthor 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.
0
 
mokuleCommented:
As to me You are right, but corrections are not big

In place of
  Writeln(F,START_TXT);
should be
  Writeln(F,Edit1.Text);
-------------
    I := 1;
    while (not Eof(F)) and (I < Desired) do
      begin
      Readln(F,str);
      if str = END_TXT  then
        Inc(I);
      end;
    Memo1.Clear;
-------------
0
 
shaneholmesCommented:
var
 I: Integer;
 LineList: TStringList;
 StartLine: Integer = -1;
 EndLine: Integer = -1;

for I:= 0 to Memo1.Lines.Count - 1 do
begin
 if Pos(edit1.Text, Memo1.Lines[I]) <> 0 then
   StartLine:= I;
 if Pos('End Point:', Memo1.Lines[I]) <> 0 then
    EndLine:= I;
 if (StartLine <> -1)  AND (EndLine <> -1) then
 break;
end;

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

LineList.SaveToFile('MyFile.Txt');

Shane
0
 
shaneholmesCommented:
TO delete, do the following

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

Shane
0
 
EE_NewguyAuthor 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
0
 
geobulCommented:
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
0
 
EE_NewguyAuthor 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.
0
 
EE_NewguyAuthor 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.
0
 
geobulCommented:
Hi,

1. removing both points:

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(title), Length(sl.Text));
      i := Pos(MemoEnd, body.Text);
      if i > 0 then begin
        body.Text := Copy(body.Text, 1, i-1);
      end;
    end;
  except
    result := false;
  end;
end;

2. If you have no clear rule where a starting point ends it's not possible to solve the second issue. For instance: you must use ':' at the end of a starting point. Only following this rule 'test3:' could be distinguished from 'test33:'. This was your example actually. Is that clear enough?

Regards, Geo
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 4
  • 3
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now