how to store large text

I have a memo and I want to store the memo.lines.text in a variable. Is there any data type that can be used in this case?

Actually, I want to store information about the received messages in a random file (file of recored). I want to store the body of the message in a variable if possible.

Your suggestions are heavily appreciated.
 
factsfaceAsked:
Who is Participating?
 
JosephGloszCommented:
The author says he wants to store the messages in a random file (file of record).  A file of some record type HAS to have a fixed length for each record. Thus, you can't use a string and you can't use a TStringList.   You can't have a file of a record type that has any part of it with a dynamic length.

If you still wanted to use a string in that record type, you could declare it with a length value (X: string[1024] for example) but that would sometimes not be enough, and most of the time, be wasteful.

But if you didn't mind being wasteful of disk space, then the following would work:

const
  MAXLENGTH = 2048;
type
  TFixedString = record
     S: string[MAXLENGTH];
  end;
var
  f: file of TFixedString;
  MyData: TFixedString.

then assign MyData.S := Memo1.Text;   (don't really need the extra 'Line' in the middle as Steve Bay writes).

If you want a file of record, something along these lines are best you can do. If you don't mind writing all the text to an actual textfile, perhaps using your own delimiters to separate the different Memo texts, then you could do that as well.  

If there were no actual CR+LF in the string you want to save, if you used a textfile, then you could easily write and access each message with just a writeln and readln.

That wouldn't waste space at least.




0
 
SteveBayCommented:
A string varable would be the most simple solution.
Str := Memo1.Line.text;
memo1.Lines.text := Str;
0
 
SteveBayCommented:
More flexability can be attained with a TStringlist

 var sList
begin
 sList :=  TStringlist.Create
 sList.Assign(Memo1.Lines);
 sList.SaveToFile('C:\File.txt');
 sList.LoadFromFile(C:\File.txt');
 Memo1.Lines.Assign(sList);
 sList.Free
end
0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

 
JosephGloszCommented:
as an addendum.  If you don't want to add extra variable to the TFixedString type, then it would be simpler to just make that string it's own type. As in:

type
  TFixedString = string[MAXLENGTH];

and then just use that.
0
 
factsfaceAuthor Commented:
Thank you very much
0
 
factsfaceAuthor Commented:
First, it works fine. Now, it gives me the following error message: String literals may have at most 255 characters.
 
0
 
JosephGloszCommented:
Usually by default, a "string" is declared as an AnsiString, which can grow to any size. However, and I forgot this, if you attach a length specifier, then Delphi is smart enough to declare it as a ShortString, which IS limited to 255 chars.

Instead, using an array of chars as an intermediary type is the way you have to go. That is, you can store them in the file of record as an array of char, and read them out as such, but you can still work with them as strings (that is, long strings or "AnsiStrings") to make it easy to manipulate.

thus redeclare the TFixedString as

type
  TFixedCharString = array[0..MAXLENGTH-1] of char;


var
  FixedCharString: TFixedCharString;
  FixedString: AnsiString;

  f: file of TFixedCharString;


then, in your code, it's just one extra line.

  FixedString := Memo1.text;  // the memo text copies into a string natively
  FixedCharString := pchar(FixedString);  


to store it:

  write(f,FixedCharString);

to read it:

  read(f,FixedCharString);

I'll work up and test a few examples for you in a couple of hours...  :)












0
 
JosephGloszCommented:
Ok sorry for the delay.  Here is the complete source for the unit I just tested.  The only real additional change is that when you assign a string from the Memo, it has to be converted to the char array with a StrPCopy command (that's a Delphi internal call).

Here is the full source of my unit.  I tested it and it works well.  Please feel free to ask if this doesn't make sense:

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Label1: TLabel;
    btnReadMemo: TButton;
    btnCloseFile: TButton;
    btnReadFile: TButton;
    btnOpenFile: TButton;
    procedure btnReadMemoClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure btnCloseFileClick(Sender: TObject);
    procedure btnReadFileClick(Sender: TObject);
    procedure btnOpenFileClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

const
  MAXLENGTH = 2048;

type
  TFixedCharString = array[0..MAXLENGTH-1] of char;
var
  FixedCharString: TFixedCharString;
  f: file of TFixedCharString;
  FixedString: AnsiString;

implementation

{$R *.dfm}

function FixedToStr(C: TFixedCharString): string;
begin
  result := C;
  SetLength(result,StrLen(C));
end;

procedure TForm1.btnReadMemoClick(Sender: TObject);
begin
  FixedString := Memo1.Text;
  StrPCopy(FixedCharString,FixedString); // copies a string into a pchar type array
  write(f,FixedCharString);
  Label1.Caption := FixedString;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  assignFile(f,'test.txt');
  rewrite(f);
end;

procedure TForm1.btnCloseFileClick(Sender: TObject);
begin
  CloseFile(f);
end;

procedure TForm1.btnReadFileClick(Sender: TObject);
begin
  read(f,FixedCharString);
  FixedString := FixedCharString;
  Label1.Caption := FixedString;
end;

procedure TForm1.btnOpenFileClick(Sender: TObject);
begin
  assignFile(f,'test.txt');
  reset(f);
end;

0
 
factsfaceAuthor Commented:
Thank you very much. Your efforts are highly appreciated.

The following piece of code equals its weight in gold:
  FixedString := Memo1.Text;
  StrPCopy(FixedCharString,FixedString); // copies a string into a pchar type array
 
Note: why do you use the following function:

function FixedToStr(C: TFixedCharString): string;
begin
  result := C;
  SetLength(result,StrLen(C));
end;
0
 
JosephGloszCommented:
Oy!  You are right. I don't actually use the FixedToStr function.  I was initially experimenting with writing my own functions with the conversions to and from the string and char array. However, the StrPCopy and the straight up assignment "FixedString := FixedCharString;" worked as well and faster.

I just simply forget to delete that function. Sorry.

Also, I almost forgot: the one and only thing you need to be careful of here is that since uses Delphi's built in pchar routines (StrPCopy, and that straight assignment) then a null char (#0) will end the string.

This is one reason why I like writing my own conversion routines sometimes. If there is a null in the string that truly supposed to be there as part of the string, then with my own routines, I can at least make sure everything works as I intended. With or without nulls.  :)


0
 
factsfaceAuthor Commented:
Thank you for clarification.
I actually try the code to write from memo to a random file then read from that random file to memo and it works fine.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.