Home

The TStringList Class

 

Introduction to the TStringList Class

 

Overview

The TStrings class appears to provide enough methods to perform any operation on any list of strings. Unfortunately, because TStrings is an abstract class, you cannot declare an instance of it, which means that you cannot create a dynamic list of strings using the TStrings class. That is one of the reasons you will use alternate classes to accomplish such a task.

The TStringList is derived from TStrings. It adds new properties and methods for operations not possible on its parent. This is because the TStrings class can only fill out a list. It cannot independently manage the items of its own list; it relies on the control that uses it.

One of the strengths of the TStringList class is that, unlike the TStrings class, it is not associated with any control, not even a control that creates a list. Therefore, you are in charge of using it as you see fit. This also allows a TStringList object to accommodate almost any control that uses a list. It also provides the primary means of exchanging items among controls of various kinds.

 

Creating a TStringList Object

Because the TStringList class is not a property of any control, whenever you need it, you must create it dynamically. Because it is not a control, you only need the new operator to declare an instance of a TStringList class. The compiler does not need to know the parent or owner of the list. For the same reason, you have the responsibility of deleting the list when you do not need it anymore.

To dynamically create a list, you must declare an instance of a TStringList class using the new operator. If you are planning to use the list inside of only one function or event, you can initiate the object as follows:

//---------------------------------------------------------------------------
void __fastcall TForm1::CreateAlist()
{
    TStringList *Categories = new TStringList;
}
//---------------------------------------------------------------------------

Such a list cannot be accessed outside of the event or function in which you created it. If you want the list to be available to more than one event or function, create it globally. This could be done on top of the source file. Here is an example:

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
TStringList *Categories = new TStringList;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------

This time, the list would be available to any event or function of the same source file. Other objects, events, or functions that are part of other units (for example if you call this form from another form) other than this one cannot access the list. The alternative, sometimes the best one, is to declare the list variable in the header file of the primary unit that would manipulate or use it. This is done in the private, public or protected sections of the unit. If only one unit will use this list, declare the variable in the private section. By contrast, if more than one unit will need it, then declare it in the public section. This time, since you cannot initialize a variable in a class, only declare a pointer to a TStringList class. Here is an example:

//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
private:
    TStringList * Categories; // User declarations
public: // User declarations
    __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

After declaring such a variable, you should initialize it in a function or event that would be called prior to any other event or function using the list. Although this can be done in the OnCreate() event of a form, probably the safest place to initialize the list is the constructor of the form. You will use the new operator to initialize the variable. Here is an example:

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
    Categories = new TStringList;
}
//---------------------------------------------------------------------------

Once you have created the list locally or globally, you can call any of its properties or methods to manipulate it.

Characteristics of a TStringList

 

The TStringList as a TString

The fundamental difference between the TStrings and the TStringList classes is that, besides the first being the parent of the second, you cannot create an instance of a TStrings class. Using the properties of inheritance, you can perform any operation on a TStringList variable that you would perform on a TStrings object.

Like a TStrings list, the primary means of filling out a TStringList object is by using either the Append() or the Add() methods. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
	TStringList * EmployeesNames = new TStringList;

	EmployeesNames->Add(274);
	EmployeesNames->Add(8);
	EmployeesNames->Add(5006);
	EmployeesNames->Add(418);
	EmployeesNames->Add(940);
}
//---------------------------------------------------------------------------

If the addition is successful, the method returns the position occupied by the argument in the list. If the list was empty, the new string would be the first, which is the 0 position because the list is zero-based. If the list already had at least one item, the argument would be added to the end of the existing items.

Sorting a List of Strings

As you add values to a list of strings, each item occupies a position in the order it was added. If you want, you can reorder the list in alphabetical, numerical, or chronological order. To support this operation, the TStringList class is equipped with a method named Sort. Its syntax is:

virtual void __fastcall Sort(void);

The sequence of events between adding items and sorting the list is important:

  • If you call the Sort() method before adding the items to the list, the list would not be sorted:
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
    	TStringList * EmployeesNames = new TStringList;
    
    	EmployeesNames->Sort();
    
    	EmployeesNames->Add(L"John");
    	EmployeesNames->Add(L"Yves");
    	EmployeesNames->Add(L"Antoine");
    	EmployeesNames->Add(L"William");
    	EmployeesNames->Add(L"Gertrude");
    	EmployeesNames->Add(L"Christine");
    	EmployeesNames->Add(L"Béatrice");
    
    	SomeList->Items = EmployeesNames;
    }
    //---------------------------------------------------------------------------
    This would produce:
     
    String List
  • If you call the Sort() method after some strings have been created, the existing list would be sorted. If new items are added, the additional list will not be sorted:
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
    	TStringList * EmployeesNames = new TStringList;
    
    	EmployeesNames->Add(L"John");
    	EmployeesNames->Add(L"Yves");
    	EmployeesNames->Add(L"Antoine");
    	EmployeesNames->Add(L"William");
    
    	EmployeesNames->Sort();
    
    	EmployeesNames->Add(L"Gertrude");
    	EmployeesNames->Add(L"Christine");
    	EmployeesNames->Add(L"Béatrice");
    
    	SomeList->Items = EmployeesNames;
    }
    //---------------------------------------------------------------------------
    This would produce:
     
    String List

To let you manage the sorting of item in a list, the TStringList class provides the Boolean Sorted property:

__property bool Sorted = {read=FSorted,write=SetSorted};

Because this is a write property, there are various ways you can use it. You can access this property at any time before or after the strings are added to a list. If you access this property and set its value to True before the strings are added to a list, you indicate that you want the items to be sorted. Consider the following example:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
	TStringList * EmployeesNames = new TStringList;

	EmployeesNames->Sorted = True;

	EmployeesNames->Add(L"John");
	EmployeesNames->Add(L"Yves");
	EmployeesNames->Add(L"Antoine");
	EmployeesNames->Add(L"William");
	EmployeesNames->Add(L"Gertrude");
	EmployeesNames->Add(L"Christine");
	EmployeesNames->Add(L"Béatrice");

	SomeList->Items = EmployeesNames;
}
//---------------------------------------------------------------------------

This would produce:

String List

In the same way, you can access this property and set its value to False to indicate that you don't want the strings to be sorted.

As a read property, you can access this property anytime to find out whether the list is sorted or not.

The List and Case-Sensitivity

When sorting the strings of a list, to let you control case-sensitivity, the TStringList class provides the CaseSensitive property, which is Boolean:

__property bool CaseSensitive = {read=FCaseSensitive,write=SetCaseSensitive};

If you set this property to True, the type and language of the characters (the encoding scheme) would be taken into consideration.

 
 
 

Home Copyright © 2010-2011 FunctionX, Inc.