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

From Lazarus wiki
Jump to navigationJump to search
(→‎TStringList: dalsze tłumaczenie na j. polski)
(14 intermediate revisions by the same user not shown)
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|zbioru]] ciągów typu string (typ zbiorowy ciągów znakowych 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 23: Line 23:
 
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ć:
 
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ć:
  
'''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.
+
'''Create''' - 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.
  
 
'''Count''' - Ta [[Property|właściwość]] jest licznikiem liczby ciągów na liście.
 
'''Count''' - Ta [[Property|właściwość]] jest licznikiem liczby ciągów na liście.
Line 95: Line 95:
  
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
// This works perfect, no double creation of stringlist... comments free to send to edgarrod71@gmail.com
+
// Działa to doskonale, bez podwójnego tworzenia listy ciągów
 
function theStringList: TStringList;
 
function theStringList: TStringList;
 
var
 
var
Line 118: Line 118:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
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.
+
Aby iterować po liście, lepiej jest użyć pętli '''while-do''' zamiast pętli '''for-to'''. Powodem jest to, że lista może być pusta, więc pętla for-to nie działa poprawnie.
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.
+
 
 +
W tym przykładzie procedura SubscriberDel jest wywoływana dla każdego identyfikatora ID na liście, a lista identyfikatorów ID jest przekazywana do procedury jako ciąg znaków (string).
  
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
Line 139: Line 140:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
=== Conversion to and from delimited strings ===
+
=== Konwersja do i z ciągów rozdzielanych ===
  
Code below will result in a stringlist, containing 4 elements ('1', '2', '3' and '4');
+
Poniższy kod spowoduje powstanie listy ciągów zawierającej 4 elementy ('1', '2', '3' i '4');
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
 
procedure Sample;
 
procedure Sample;
Line 155: Line 156:
  
  
Respectively next code will assemble a stringlist into a delimited string ('1;2;3;4'):
+
Odpowiednio następny kod złoży listę ciągów w ciąg rozdzielony średnikami ('1;2;3;4'):
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
 
function Sample2 : string;
 
function Sample2 : string;
Line 172: Line 173:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 +
Zwróć uwagę, że separator to znak typu char, a '''nie''' ciąg typu string! Jeśli separatorem jest ciąg (na przykład „\n”), to możesz użyć poniższego kodu, aby uzyskać listę ciągów zawierającą 4 elementy („1”, „2”, „3” i „4”):
  
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'):
 
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
 
procedure Sample;
 
procedure Sample;
Line 186: Line 186:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Vice versa, next [[Function|function]] will return „1\n2\n3‟:
+
I odwrotnie, następna funkcja zwróci „1\n2\n3”:
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
 
Function Sample : string;
 
Function Sample : string;
Line 202: Line 202:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
==File Handling==
+
==Obsługa plików==
  
When using the TStringList you have 2 file handling [[Procedue|procedures]]: '''SaveToFile''' and '''LoadFromFile'''.
+
Korzystając z TStringList, masz do dyspozycji 2 [[Procedue|procedury]] obsługi plików: '''SaveToFile''' i '''LoadFromFile'''.
SavetoFile will save all strings in the list to a file.
+
SavetoFile zapisze wszystkie ciągi z listy do pliku.
LoadFromFile will open the file and add the file data to the list string by string.
+
LoadFromFile otworzy plik i doda dane pliku do listy ciągów.
  
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
Line 228: Line 228:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
You just opened a file, edited it and saved it right back to were it was!
+
Właśnie otworzyłeś plik, wyedytowałeś go i zapisałeś z powrotem tam, gdzie był!
  
== Sorting ==
+
== Sortowanie ==
  
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.
+
Procedura Find wymaga posortowanej listy. Najłatwiejszym sposobem jest ustawienie właściwości Sorted na True, dzięki temu nowe elementy dodawane do listy zostaną wstawione we właściwej pozycji. Ma to kilka dodatkowych efektów ubocznych, po pierwsze, nie możesz użyć procedury Insert(), użyj tylko Add(). Po drugie, ustawia ona właściwość Duplicates, jej domyślne ustawienie to „dupIgnore”, co oznacza, że ​​próby dodania identycznych wpisów będą ignorowane. Jednak wywołanie AddObject(), które mają identyczny ciąg znaków i jakiś nowy Object, spowoduje, że nowy Object zastąpi istniejący.
  
==Dynamic string array comparison==
+
==Porównanie z dynamiczną tablicą ciągów==
  
TStringList is simply an [[object-oriented programming|object-oriented]] version of a dynamic string array. Some methods have analogs:
+
TStringList to po prostu zorientowana obiektowo wersja dynamicznej tablicy ciągów. Niektóre metody mają tu nawet swoje odpowiedniki:
  
 
{| class="wikitable"
 
{| class="wikitable"
 
|-  
 
|-  
! Operation !! array of string !! TStringList
+
! Operacja !! Tablica ciągów !! TStringList
 
|-  
 
|-  
| Variable declaration || StringList: array of string; || StringList: TStringList;
+
| Deklaracja zmiennych || StringList: array of string; || StringList: TStringList;
 
|-
 
|-
| Initialization || implicit constructor || StringList := TStringList.Create
+
| Inicjalizacja || domyślnie constructor || StringList := TStringList.Create
 
|-
 
|-
| Set size || SetLength(StringList, X); || StringList.Size := X;
+
| Ustawenie rozmiaru || SetLength(StringList, X); || StringList.Size := X;
 
|-
 
|-
| Get size || X := Length(StringList); || X := StringList.Count;
+
| Odczytanie rozmiaru || X := Length(StringList); || X := StringList.Count;
 
|-
 
|-
| Add item || SetLength(StringList, Length(StringList) + 1); StringList[Length(StringList) - 1] := X; || StringList.Add(X);
+
| Dodanie elementu || 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);
+
| Usunięcie elememtu || 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;
+
| Usunięcie wszystkich elementów || SetLength(StringList, 0); || StringList.Clear;
 
|-
 
|-
| Finalization || implicit destructor || StringList.Free;
+
| Finalizacja || domyślnie destructor || StringList.Free;
 
|}
 
|}
  
However, TStringList offers much more functionality than a basic structure such as a dynamic array.
+
Jednak TStringList oferuje znacznie więcej funkcji niż podstawowa struktura, taka jak tablica dynamiczna.
  
==Keep Learning==
+
==Dalsza nauka==
TStringList has many other interesting features:
+
TStringList ma wiele innych interesujących cech:
# It allows you to sort the strings
+
# Pozwala na sortowanie ciągów
# It allows you to limit the list to only unique strings
+
# Pozwala ograniczyć listę tylko do unikalnych ciągów
# You can get the text of all strings as a single string using the '''Text''' property.
+
# Możesz pobrać tekst wszystkich ciągów jako jeden ciąg przy użyciu właściwości '''Text'''.
# You can store an object or other data next to the string
+
# Obok ciągu można przechowywać obiekt lub inne dane
  
You can learn all the different procedures, functions and properties. See [[doc:rtl/classes/tstringlist.html|TStringList documentation]]... or the help in Lazarus.
+
Możesz nauczyć się różnych procedur, funkcji i właściwości. Zobacz [[doc:rtl/classes/tstringlist.html|dokumentacja TStringList]] ... lub zajrzyj do pomocy w Lazarusie.
  
... and you might like to extend this tutorial if you feel like it.
+
... i możesz rozszerzyć ten samouczek, jeśli masz na to ochotę.
  
== See also ==
+
== Zobacz także ==
* [[Character and string types]]
+
* [[Character and string types|Typy znakowe i ciągi znaków]]

Revision as of 10:46, 17 September 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 zbioru ciągów typu string (typ zbiorowy ciągów znakowych 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 - 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;
// Działa to doskonale, bez podwójnego tworzenia listy ciągów
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;

Aby iterować po liście, lepiej jest użyć pętli while-do zamiast pętli for-to. Powodem jest to, że lista może być pusta, więc pętla for-to nie działa poprawnie.

W tym przykładzie procedura SubscriberDel jest wywoływana dla każdego identyfikatora ID na liście, a lista identyfikatorów ID jest przekazywana do procedury jako ciąg znaków (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;

Konwersja do i z ciągów rozdzielanych

Poniższy kod spowoduje powstanie listy ciągów zawierającej 4 elementy ('1', '2', '3' i '4');

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


Odpowiednio następny kod złoży listę ciągów w ciąg rozdzielony średnikami ('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;

Zwróć uwagę, że separator to znak typu char, a nie ciąg typu string! Jeśli separatorem jest ciąg (na przykład „\n”), to możesz użyć poniższego kodu, aby uzyskać listę ciągów zawierającą 4 elementy („1”, „2”, „3” i „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;

I odwrotnie, następna funkcja zwróci „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;

Obsługa plików

Korzystając z TStringList, masz do dyspozycji 2 procedury obsługi plików: SaveToFile i LoadFromFile. SavetoFile zapisze wszystkie ciągi z listy do pliku. LoadFromFile otworzy plik i doda dane pliku do listy ciągów.

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.

Właśnie otworzyłeś plik, wyedytowałeś go i zapisałeś z powrotem tam, gdzie był!

Sortowanie

Procedura Find wymaga posortowanej listy. Najłatwiejszym sposobem jest ustawienie właściwości Sorted na True, dzięki temu nowe elementy dodawane do listy zostaną wstawione we właściwej pozycji. Ma to kilka dodatkowych efektów ubocznych, po pierwsze, nie możesz użyć procedury Insert(), użyj tylko Add(). Po drugie, ustawia ona właściwość Duplicates, jej domyślne ustawienie to „dupIgnore”, co oznacza, że ​​próby dodania identycznych wpisów będą ignorowane. Jednak wywołanie AddObject(), które mają identyczny ciąg znaków i jakiś nowy Object, spowoduje, że nowy Object zastąpi istniejący.

Porównanie z dynamiczną tablicą ciągów

TStringList to po prostu zorientowana obiektowo wersja dynamicznej tablicy ciągów. Niektóre metody mają tu nawet swoje odpowiedniki:

Operacja Tablica ciągów TStringList
Deklaracja zmiennych StringList: array of string; StringList: TStringList;
Inicjalizacja domyślnie constructor StringList := TStringList.Create
Ustawenie rozmiaru SetLength(StringList, X); StringList.Size := X;
Odczytanie rozmiaru X := Length(StringList); X := StringList.Count;
Dodanie elementu SetLength(StringList, Length(StringList) + 1); StringList[Length(StringList) - 1] := X; StringList.Add(X);
Usunięcie elememtu for I := Index to Length(StringList) - 2 do StringList[I] := StringList[I + 1]; SetLength(StringList, Length(StringList) - 1); StringList.Delete(Index);
Usunięcie wszystkich elementów SetLength(StringList, 0); StringList.Clear;
Finalizacja domyślnie destructor StringList.Free;

Jednak TStringList oferuje znacznie więcej funkcji niż podstawowa struktura, taka jak tablica dynamiczna.

Dalsza nauka

TStringList ma wiele innych interesujących cech:

  1. Pozwala na sortowanie ciągów
  2. Pozwala ograniczyć listę tylko do unikalnych ciągów
  3. Możesz pobrać tekst wszystkich ciągów jako jeden ciąg przy użyciu właściwości Text.
  4. Obok ciągu można przechowywać obiekt lub inne dane

Możesz nauczyć się różnych procedur, funkcji i właściwości. Zobacz dokumentacja TStringList ... lub zajrzyj do pomocy w Lazarusie.

... i możesz rozszerzyć ten samouczek, jeśli masz na to ochotę.

Zobacz także