Difference between revisions of "TStringList-TStrings Tutorial/pl"

From Lazarus wiki
Jump to navigationJump to search
(Tłumaczenie na j. polski pierwszego przykładu)
(→‎TStringList: dalsze tłumaczenie na j. polski)
Line 2: Line 2:
 
==TStringList==
 
==TStringList==
  
[[doc:rtl/classes/tstringlist.html|TStringList]] (lub jego rodzic [[doc:rtl/classes/tstrings.html|TStrings]]) jest bardzo podobna do fantazyjnej [[Dynamic array|tablicy dynamicznej]] lub [[Set|zbiór]] ciągów typu string (zbiór ciągów nie jest możliwy w FPC). ten typ danych jest bardzo przydatny podczas programowania i mam zamiar nauczyć Cię podstaw obsługi TStringList!
+
[[doc:rtl/classes/tstringlist.html|TStringList]] (lub jego rodzic [[doc:rtl/classes/tstrings.html|TStrings]]) jest bardzo podobna do fantazyjnej [[Dynamic array|tablicy dynamicznej]] lub [[Set|zbiór]] ciągów typu string (zbiór ciągów nie jest możliwy w FPC). Ten typ danych jest bardzo przydatny podczas programowania i mam zamiar nauczyć Cię podstaw obsługi TStringList!
  
 
===Prosty przykład===
 
===Prosty przykład===
Line 21: Line 21:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
This is a simple [[Command-line_interface|console program]] that will create and add one string to a stringlist.
+
Jest to prosty [[Command-line_interface|program konsolowy]], który utworzy i doda jeden ciąg (string) do listy ciągów (stringlist). Oto kilka rzeczy, które powinieneś wiedzieć:
Now here's some things you should know:
 
  
'''Create''' - Will create the string list for modifying. If you use [[Constructor|<syntaxhighlight lang="pascal" inline>constructor</syntaxhighlight>]] '''Create''', you have to later '''Free'''.
+
'''Create''' - Will create the string list for modifying. Stworzy listę ciągów, którą potem możesz modyfikować. Jeśli używasz konstruktora [[Constructor|<syntaxhighlight lang="pascal" inline>constructor</syntaxhighlight>]] '''Create''', musisz później zwolnić jego pamięć za pomocą '''Free'''. Wywołanie <syntaxhighlight lang="pascal" inline>free</syntaxhighlight> skutkuje wywołaniem destruktora [[Destructor|<syntaxhighlight lang="pascal" inline>destructor</syntaxhighlight>]] <syntaxhighlight lang="pascal" inline>Destroy</syntaxhighlight>, który niszczy listę i uwalnia zajmowaną przez nią pamięć. Jeśli tego nie zrobisz, to program nie ulegnie awarii, ale też nie zwolni całej zajmowanej pamięci i nastąpi tzw. wyciek pamięci.
Calling <syntaxhighlight lang="pascal" inline>free</syntaxhighlight> causes [[Destructor|<syntaxhighlight lang="pascal" inline>destructor</syntaxhighlight>]] a <syntaxhighlight lang="pascal" inline>Destroy</syntaxhighlight> invitation and release the memory it takes. If not, you program will not crash, but it will not release all the memory it occupied: a memory leak.
 
  
'''Count''' - This [[Property|property]] is a counter for the number of strings in the List.
+
'''Count''' - Ta [[Property|właściwość]] jest licznikiem liczby ciągów na liście.
  
'''Add''' - This [[Method|method]] allows you to add one string to the stringlist. It is a function that will return the '''Index''' of the String. This is where the counter comes in handy.
+
'''Add''' - Ta [[Method|metoda]] umożliwia dodanie jednego ciągu do listy ciągów. Jest to funkcja, która zwraca indeks ciągu. Tutaj z pomocą przychodzi licznik.
  
'''Delete''' - Will delete a string from the stringlist. Just know that you do not simply input the string, you have to input the index of the string. Like I said: it's like a fancy Dynamic Array.
+
'''Delete''' - Usuwa ciąg (string) z listy ciągów (stringlist). Musisz wiedzieć, że nie podajesz ciągu znaków, które chcesz usunąć, ale musisz wprowadzić indeks tego ciągu. Jak powiedziałem: to jak fantazyjna tablica dynamiczna.
  
'''IndexOf''' - Will return the index of the string in the list. If it is not found it returns -1.
+
'''IndexOf''' - Zwróci indeks ciągu na liście. Jeśli nie zostanie on znaleziony, to zwraca -1.
  
'''Clear''' - Will clear the list.
+
'''Clear''' - Czyści całą listę.
  
===Expanded Example===
+
===Rozszerzony przykład===
  
How about a more juicy example, eh?
+
A może bardziej soczysty przykład, co?
  
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
Line 55: Line 53:
 
   Writeln('String List Test');
 
   Writeln('String List Test');
 
   repeat
 
   repeat
     Writeln('Enter a string to add (type EXIT to stop adding strings)');
+
     Writeln('Wpisz ciąg do dodania (wpisz KONIEC, aby zatrzymać dodawanie ciągów)');
 
     Readln(S);  
 
     Readln(S);  
     if (S = 'EXIT') then  
+
     if (S = 'KONIEC') then  
       Break; // exit the loop
+
       Break; // wyjście z pętli
 
      
 
      
 
     if (S <> '') then
 
     if (S <> '') then
 
     begin
 
     begin
 
       Counter := Str.Add(S);
 
       Counter := Str.Add(S);
       Writeln('String: ' + S + ' was Added!');
+
       Writeln('Ciąg: ' + S + ' został dodany!');
       Writeln('Index is: ' + IntToStr(Counter)); // The counter will always become the index of the last thing added
+
       Writeln('Jego index to: ' + IntToStr(Counter)); // Licznik zawsze będzie indeksem ostatnio dodanej rzeczy
 
     end  
 
     end  
 
     else  
 
     else  
 
     begin
 
     begin
       Writeln('No data entered...');
+
       Writeln('Nie wprowadzono żadnych danych...');
 
     end;
 
     end;
   until (S = 'EXIT');
+
   until (S = 'KONIEC');
   writeln('Contents of the TStringList: '+ Str.CommaText);
+
   writeln('Zawartość TStringList: '+ Str.CommaText);
   Str.Free; //release the memory again
+
   Str.Free; //zwolnij pamięć
 
end.
 
end.
 
</syntaxhighlight>
 
</syntaxhighlight>
  
However, to avoid possible memory leaks you should always use a [[Try]] - [[Finally]] block where possible for this, so you get something like:
+
Jednak, aby uniknąć możliwych wycieków pamięci, zawsze powinieneś używać bloku [[Try]] - [[Finally]] wszędzie, gdzie to możliwe, aby uzyskać coś takiego:
  
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
Line 87: Line 85:
 
try
 
try
 
   ...
 
   ...
   // do things with your stringlist
+
   // rób różne rzeczy z twoją listą stringów (stringlist)
 
   ...
 
   ...
 
finally
 
finally

Revision as of 21:23, 25 August 2020

Deutsch (de) English (en) español (es) suomi (fi) français (fr) polski (pl) русский (ru)

TStringList

TStringList (lub jego rodzic TStrings) jest bardzo podobna do fantazyjnej tablicy dynamicznej lub zbiór ciągów typu string (zbiór ciągów nie jest możliwy w FPC). Ten typ danych jest bardzo przydatny podczas programowania i mam zamiar nauczyć Cię podstaw obsługi TStringList!

Prosty przykład

program StrList;
{$mode objfpc}
uses
 Classes, SysUtils;
var
  Str: TStringList;
begin
  Str := TStringList.Create; // Jest to potrzebne podczas korzystania z tej klasy (lub większości klas)
  Str.Add('Jakiś ciąg znaków!');
  writeln('Lista ciągów ma teraz ' + IntToStr(Str.Count) + ' ciąg(ów).');
  Readln;
  Str.Free; //Zwolnij pamięć używaną przez tę instancję stringlist
end.

Jest to prosty program konsolowy, który utworzy i doda jeden ciąg (string) do listy ciągów (stringlist). Oto kilka rzeczy, które powinieneś wiedzieć:

Create - Will create the string list for modifying. Stworzy listę ciągów, którą potem możesz modyfikować. Jeśli używasz konstruktora constructor Create, musisz później zwolnić jego pamięć za pomocą Free. Wywołanie free skutkuje wywołaniem destruktora destructor Destroy, który niszczy listę i uwalnia zajmowaną przez nią pamięć. Jeśli tego nie zrobisz, to program nie ulegnie awarii, ale też nie zwolni całej zajmowanej pamięci i nastąpi tzw. wyciek pamięci.

Count - Ta właściwość jest licznikiem liczby ciągów na liście.

Add - Ta metoda umożliwia dodanie jednego ciągu do listy ciągów. Jest to funkcja, która zwraca indeks ciągu. Tutaj z pomocą przychodzi licznik.

Delete - Usuwa ciąg (string) z listy ciągów (stringlist). Musisz wiedzieć, że nie podajesz ciągu znaków, które chcesz usunąć, ale musisz wprowadzić indeks tego ciągu. Jak powiedziałem: to jak fantazyjna tablica dynamiczna.

IndexOf - Zwróci indeks ciągu na liście. Jeśli nie zostanie on znaleziony, to zwraca -1.

Clear - Czyści całą listę.

Rozszerzony przykład

A może bardziej soczysty przykład, co?

program StrList2;
{$mode ObjFPC}
uses
Classes, SysUtils;

var
  Str: TStringList;
  S: String;
  Counter: Integer;
begin
  Str := TStringList.Create;
  Writeln('String List Test');
  repeat
    Writeln('Wpisz ciąg do dodania (wpisz KONIEC, aby zatrzymać dodawanie ciągów)');
    Readln(S); 
    if (S = 'KONIEC') then 
      Break; // wyjście z pętli
    
    if (S <> '') then
    begin
      Counter := Str.Add(S);
      Writeln('Ciąg: ' + S + ' został dodany!');
      Writeln('Jego index to: ' + IntToStr(Counter)); // Licznik zawsze będzie indeksem ostatnio dodanej rzeczy
    end 
    else 
    begin
      Writeln('Nie wprowadzono żadnych danych...');
    end;
  until (S = 'KONIEC');
  writeln('Zawartość TStringList: '+ Str.CommaText);
  Str.Free; //zwolnij pamięć
end.

Jednak, aby uniknąć możliwych wycieków pamięci, zawsze powinieneś używać bloku Try - Finally wszędzie, gdzie to możliwe, aby uzyskać coś takiego:

var
  slist: TStringList;

...

slist := TStringList.Create;
try
  ...
  // rób różne rzeczy z twoją listą stringów (stringlist)
  ...
finally
  if Assigned(slist) then
    FreeAndNil(slist);
end;
// This works perfect, no double creation of stringlist... comments free to send to edgarrod71@gmail.com
function theStringList: TStringList;
var
 J: integer;
begin
  result := TStringList.Create;
  for J:=0 to 10 do
    result.add(intToStr(J));
end;

procedure Caller;
var
  SL: TStringList;
  K: integer;
begin
  SL := theStringList;
  for K:=0 to pred(SL.Count) do
    writeln(SL[K]);
  if assigned(SL) then
    SL.Free;
end;

To iterate through the list it is better to use the while-do loop instead of the for-to loop. The reason is that the list can be empty, then the for-to loop does not work correctly. In this example, SubscriberDel procedure is called for each ID in the List and the list of the IDs is passed to the procedure as a string.

procedure SubscribersDelete(const Subscriber_ID: string);
var
  List : TStringList; 
  i : Integer;
begin
  List := TStringList.Create;
  List.Text := Subscriber_ID;
  i := 0;
  while i < List.Count do
    begin
      SubscriberDel(List.Strings[i]);
      inc(i);
    end;
  List.Free;
end;

Conversion to and from delimited strings

Code below will result in a stringlist, containing 4 elements ('1', '2', '3' and '4');

procedure Sample;
var
    MyStringList: TStringList=nil;
begin
     MyStringList:= TStringList.create;
     MyStringList.Delimiter := ';';
     MyStringList.DelimitedText:='1;2;3;4';
     MyStringList.free;
end;


Respectively next code will assemble a stringlist into a delimited string ('1;2;3;4'):

function Sample2 : string;
var
    MyStringList: TStringList=nil;
begin
     MyStringList:= TStringList.create;
     MyStringList.Delimiter := ';';
     MyStringList.Add('1');
     MyStringList.Add('2');
     MyStringList.Add('3');
     MyStringList.Add('4');
     Result :=MyStringList.DelimitedText;
     MyStringList.free;
end;


Note that Delimter is a character, not a string! If your separator is a string (for example „\n‟), you could use code below, to get a stringlist, containing 4 elements ('1', '2', '3' and '4'):

procedure Sample;
var
    MyStringList: TStringList=nil;
begin
     MyStringList:= TStringList.create;
     MyStringList.text:=StringReplace('1\n2\n3\n4','\n',Lineending,[rfReplaceAll, rfIgnoreCase]);
     MyStringList.free;
end;

Vice versa, next function will return „1\n2\n3‟:

Function Sample : string;
var
    MyStringList: TStringList=nil;
begin
     MyStringList:= TStringList.create;
     MyStringList.SkipLastLineBreak := True;
     MyStringList.add('1');
     MyStringList.add('2');
     MyStringList.add('3');
     result := StringReplace(MyStringList.Text,Lineending,'\n', [rfReplaceAll, rfIgnoreCase]);
     MyStringList.free;
end;

File Handling

When using the TStringList you have 2 file handling procedures: SaveToFile and LoadFromFile. SavetoFile will save all strings in the list to a file. LoadFromFile will open the file and add the file data to the list string by string.

program StrListFile;
{$mode objfpc}
uses
 Classes, SysUtils;

var
  Str: TStringList;
begin
  Str := TStringList.Create;
  try
    Str.LoadFromFile('SomeFile.txt');
    Str.Add('Hello');
    Str.SaveToFile('SomeFile.txt');
  finally
    Str.Free;
  end;
end.

You just opened a file, edited it and saved it right back to were it was!

Sorting

The Find procedure requires that the list be sorted. The easiest approach is to set its Sorted property to True, then new items added to the list will be inserted in the correct position. This has a few extra side effects, firstly, you cannot use the Insert() procedure, use only Add(). Secondly, it sets the Duplicates property, its default setting is "dupIgnore" which means attempts to Add identical entries will be ignored. However, calls to AddObject() that have an identical string and a new Object, the new Object replaces the existing one.

Dynamic string array comparison

TStringList is simply an object-oriented version of a dynamic string array. Some methods have analogs:

Operation array of string TStringList
Variable declaration StringList: array of string; StringList: TStringList;
Initialization implicit constructor StringList := TStringList.Create
Set size SetLength(StringList, X); StringList.Size := X;
Get size X := Length(StringList); X := StringList.Count;
Add item SetLength(StringList, Length(StringList) + 1); StringList[Length(StringList) - 1] := X; StringList.Add(X);
Delete item for I := Index to Length(StringList) - 2 do StringList[I] := StringList[I + 1]; SetLength(StringList, Length(StringList) - 1); StringList.Delete(Index);
Remove all items SetLength(StringList, 0); StringList.Clear;
Finalization implicit destructor StringList.Free;

However, TStringList offers much more functionality than a basic structure such as a dynamic array.

Keep Learning

TStringList has many other interesting features:

  1. It allows you to sort the strings
  2. It allows you to limit the list to only unique strings
  3. You can get the text of all strings as a single string using the Text property.
  4. You can store an object or other data next to the string

You can learn all the different procedures, functions and properties. See TStringList documentation... or the help in Lazarus.

... and you might like to extend this tutorial if you feel like it.

See also