strings and string lists in Delphi
introduction
in the beginning, a string in Turbo Pascal and in Delphi was 8-bit and thus limited to 255 characters (char) and is semantically equivalent to an array
0..255 of char - this string type is now known as a
short string
the zero position was reserved to store the actual string length used
one could define a shorter string by using string[x] where x is the maximum length to be available
one could determine the actual length used by accessing the str[0] value
Delphi 1 being 16 bit, introduced the PChar which was equivalent to the char pointer in the C language and in 16-bit Windows could be up to 16-bits long.
a PChar is very different to a short string in that it is a pointer and not just memory allocated on a memory stack.
one cannot just assign a string value to a PChar, the programmer needs to allocate and deallocate memory as needed by using various functions such as StrAlloc(), StrDispose() and use functions such as StrCopy(p, str) to assign a string to a pchar.
determining length of a pchar uses much more resources than to do so for a string.
when 32 bit Windows arrived, Delphi introduced a 32bit string Long String (now called AnsiString) to provide more efficient processing than resorting to pchars.
each character holds only one byte (hence the AnsiString terminology when Unicode two-byte strings were later introduced)
the length was again stored in the zero byte and the string could be up to 2Gb in length
BUT unlike short string:
it is reference counted and automatically managed
an AnsiString variable is actually a pointer to the first character of the string in memory. Thus if s = empty string then s is actually a nil pointer value.
it is null terminated just like a pchar and the C language null-terminated strings used by Windows, and thus plays with pchars very nicely
from Windows 2000 onwards, it was important to support Unicode
WideStrings, particularly as this became the main internal Windows
API string and was also used by OLE functions
then came immutable strings in .NET
all .NET strings are immutable ie. once a value is set, it cannot be simply changed but a new string must be made and the old one discarded
hence the introduction of the TStringBuilder class in Delphi 2009 (see below) which uses a buffer to handle this
then along came cross-platform zero-based strings
string routines
other routines
TStringList and TStrings
TStringlist class allows storage of a number of strings, similar to lines of a memo
whilst TStringList is derived from TStrings, you should use TStringlist rather than TStrings as TStrings have some methods that are abstract and not implemented (eg. clear, delete, insert) - an exception is perhaps when you are passing as a parameter in a procedure or function as this would allow passing any descendant including Memo.lines, Listbox.items, etc.
you must create an instance then free it when you are finished with it
it allows you to sort the strings
it allows you to limit the list to only unique strings
you can get the text of all strings as a single string using the Text property
you can store an object or other data next to the string
to add more strings, use append
you can use commatext, delimitedtext, or just text to get or set the text
you can access a string by its index value
there are many methods one can use including LoadFromFile and SaveToFile and sort
see:
var
slist: TStringList;
begin
slist := TStringList.Create;
try
...
// do things with your stringlist
...
finally
if Assigned(slist) then
FreeAndNil(slist);
end;
end;
TStringBuilder
-
TStringBuilder class is an implementation of, and is completely compatible with the .NET framework's StringBuilder (MSDN) class
in use, the code is similar to that when using a TStringList
procedure TMainForm.Button1Click(Sender: TObject);
var
SB: TStringBuilder;
begin
{ Increase the click count for the button. }
Inc(FClickCount);
{ Create a new instance of TStringBuilder. }
SB := TStringBuilder.Create();
try
{ Append the message to the string builder. }
SB.Append('This button was pressed ').
AppendFormat('%d times', [FClickCount]);
{ Show a message; use ToString to access the built string. }
MessageDlg(SB.ToString(), mtInformation, [mbOK], 0);
{ Clear the string builder to allow building another string. }
SB.Clear();
if SB.Length <> 0 then
MessageDlg('This cannot happen! Length must be 0 after clear!', mtError, [mbOK], 0);
{ Build another string with 2 lines. }
SB.Append('The name of the button was:').
AppendLine().
Append((Sender as TButton).Name);
{ Show another message and free the string builder instance. }
MessageDlg(SB.ToString(), mtInformation, [mbOK], 0);
finally
SB.Free;
end;
end;