[gelöst] function mit Stringlisten Verarbeitung

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Linkat
Lazarusforum e. V.
Beiträge: 566
Registriert: So 10. Sep 2006, 23:24
OS, Lazarus, FPC: Linux Mint 22.1; Lazarus 4.0 FPC 3.2.2; RaspiOS
CPU-Target: AMD 64, ARM 64
Wohnort: nr Stuttgart

[gelöst] function mit Stringlisten Verarbeitung

Beitrag von Linkat »

Hallo,
bin gerade dabei eine Funktion zur Bearbeitung von Stringlisten zu schreiben. Beispielhaft habe ich hier eine Funktion, in der alle Großbuchstaben in Kleinbuchstaben verwandelt werden. Die Funktion funktioniert wunderbar. Die Stringliste slt wird übergeben, die einzelnen Strings werden verarbeitet und letzt endlich wird die Stringliste übergeben.

Code: Alles auswählen

function sl_transfer(slt:TStringList):TStringList;
var i    :integer;
begin
  for i:=0 to slt.Count-1 do slt.Strings[i]:=LowerCase(slt.Strings[i]);
  sl_transfer:=slt;
end;
Meine Frage ist: Warum muss ich die Stringlisten slt und sl_transfer nicht mit

Code: Alles auswählen

slt.create;
sl_transfer.create;
Korrektur: (Danke lrlr)
slt:=TStringList.Create;
sl_transfer:=TStringList.Create;

erzeugen, bzw. mit

Code: Alles auswählen

slt.free;
sl_transfer.free;
wieder freigeben?

Gruß, Linkat
Zuletzt geändert von Linkat am Di 19. Jan 2010, 14:48, insgesamt 2-mal geändert.
Linux Mint 21.3; Lazarus 3.4 FPC 3.2.2; RaspiOS

Benutzeravatar
theo
Beiträge: 10958
Registriert: Mo 11. Sep 2006, 19:01

Re: function mit Stringlisten Verarbeitung

Beitrag von theo »

Irgendwo createst du ja die StringList, die du an die Fkt. übergibst.
Danach zeigt alles nur auf DIESE eine Stringlist.
Du könntest die function sogar ohne Resultat, also als procedure machen.
Du übergibst ja nur den Pointer, danach arbeitet deine Fkt auf dem "Original".
Der Pointer den du zurückgibst ist der gleiche den du mitgibst, also eine überflüssige Aktion.

Das Ganze macht aber sowieso wenig Sinn.
Mach doch:

uses LCLProc; //Wegen utf8

Sl.Text:=UTF8LowerCase(Sl.Text);

Linkat
Lazarusforum e. V.
Beiträge: 566
Registriert: So 10. Sep 2006, 23:24
OS, Lazarus, FPC: Linux Mint 22.1; Lazarus 4.0 FPC 3.2.2; RaspiOS
CPU-Target: AMD 64, ARM 64
Wohnort: nr Stuttgart

Re: function mit Stringlisten Verarbeitung

Beitrag von Linkat »

Hallo theo,
vielen Dank für den Hinweis mit der "Pointer-Philosophie". Da ist was dran.
Mit sl.text habe ich bisher noch nicht gearbeitet muss ich mal probieren. Aber in meinem Fall ist die LowerCase-Umwandlung ja nur beispielhaft. In Realität muss ich längere Strings mit Messdaten zerlegen.

Gruß, Linkat
Linux Mint 21.3; Lazarus 3.4 FPC 3.2.2; RaspiOS

lrlr
Beiträge: 127
Registriert: Di 3. Nov 2009, 09:48

Re: function mit Stringlisten Verarbeitung

Beitrag von lrlr »

>slt.create;

da stellts einem ja die haare auf ;-)

slt := TStringList.Create;

>sl_transfer.create;

die verwendest ja garnicht, also brauchst die auch nicht createn..

sl_transfer:=slt;

also ENTWEDER: du machst eine 2. stringliste, füllst diese mit LowerCase strings.. und lässt die originale bestehen..

ODER überschreibst die alten string (so wie du es machst)
slt.Strings:=LowerCase(slt.Strings);

dann brauchst aber keine funktion mit rückgabewert...

Linkat
Lazarusforum e. V.
Beiträge: 566
Registriert: So 10. Sep 2006, 23:24
OS, Lazarus, FPC: Linux Mint 22.1; Lazarus 4.0 FPC 3.2.2; RaspiOS
CPU-Target: AMD 64, ARM 64
Wohnort: nr Stuttgart

Re: function mit Stringlisten Verarbeitung

Beitrag von Linkat »

Hängt euch bitte nicht zu sehr an dem recht einfachen Beispiel mit der Lowercase-Funktion auf. Das Beispiel ist nicht gut gewählt. Hier trat kein Fehler auf, da die Stringlisten gleich groß sind.

Mir geht es hier mehr ums Prinzip. Kann eine Funktion eine Stringliste übernehmen, sie bearbeiten und wieder zurückgeben.

Folgende function sl_transfer2 soll alle Strings mit einem 'H' entfernen. (Mir geht jetzt weniger darum, wie man Wörter mit H entfernen kann, als dass die Stringliste in der Größe verändert wird.)

Code: Alles auswählen

function sl_transfer2(slt:TStringList):TStringList;
var i,j  :integer;
    s    :string;
    sli   :TStringList;
    vorhanden   :boolean;
begin
  sli:=TStringList.Create;
  for i:=0 to slt.Count-1 do begin
    s:=slt.Strings[i];
    vorhanden:=false;
    for j:=0 to length(s) do if s[j]='H' then vorhanden:=true;
    if not vorhanden then sli.Add(s);
  end;
  sl_transfer2:=sli;
  sli.Free;   //  <-- wird diese Zeile entfernt, tritt kein Fehler auf
end;


Hier tritt ein Fehler "Project raised exception class 'External : SIGSEGV'" auf.

Wenn ich sli.Free; entferne. Dann läuft das Programm ohne Fehlermeldung.
Warum kann ich die lokale Stringliste sli nicht freigeben?

Gruß, Linkat
Linux Mint 21.3; Lazarus 3.4 FPC 3.2.2; RaspiOS

Benutzeravatar
theo
Beiträge: 10958
Registriert: Mo 11. Sep 2006, 19:01

Re: function mit Stringlisten Verarbeitung

Beitrag von theo »

Linkat hat geschrieben: Wenn ich sli.Free; entferne. Dann läuft das Programm ohne Fehlermeldung.
Warum kann ich die lokale Stringliste sli nicht freigeben?
Weil sie das Resultat deiner Funktion ist!!
Du brauchst die Variable sli gar nicht.

Mach einfach:
Result:=TStringList.create;
if blah then
Result.add(S);

Linkat
Lazarusforum e. V.
Beiträge: 566
Registriert: So 10. Sep 2006, 23:24
OS, Lazarus, FPC: Linux Mint 22.1; Lazarus 4.0 FPC 3.2.2; RaspiOS
CPU-Target: AMD 64, ARM 64
Wohnort: nr Stuttgart

Re: function mit Stringlisten Verarbeitung

Beitrag von Linkat »

Vielen Dank theo,
ich denke ich habe es verstanden.

Dies scheint jetzt eine vernünftige vorgehensweise zu sein:

Code: Alles auswählen

function sl_transfer2(slt:TStringList):TStringList;
var i,j  :integer;
    s    :string;
    vorhanden   :boolean;
begin
  result:=TStringList.Create;
  for i:=0 to slt.Count-1 do begin
    s:=slt.Strings[i];
    vorhanden:=false;
    for j:=0 to length(s) do if s[j]='H' then vorhanden:=true;
    if not vorhanden then result.Add(s);
  end;
end;

Gruß, Linkat
Linux Mint 21.3; Lazarus 3.4 FPC 3.2.2; RaspiOS

Benutzeravatar
theo
Beiträge: 10958
Registriert: Mo 11. Sep 2006, 19:01

Re: function mit Stringlisten Verarbeitung

Beitrag von theo »

Linkat hat geschrieben:Vielen Dank theo,
ich denke ich habe es verstanden.
OK, Aber Achtung: Die resultierende Stringlist muss nach Gebrauch irgendwo wieder befreit werden!

Ausserdem würde ich noch ein Break einbauen:

Code: Alles auswählen

for j:=0 to length(s) do if s[j]='H' then 
 begin 
   vorhanden:=true;
   break; //"vorhanden" wird nicht mehr wahrer
 end;

Antworten