Recent

Author Topic: TStrings to String and vice versa  (Read 3328 times)

dietmar

  • Full Member
  • ***
  • Posts: 170
TStrings to String and vice versa
« on: September 28, 2021, 02:43:58 pm »
Hi,

I am trying to convert the lines of a memo to a string to store it as a VARCHAR in a sqlite database. The other way round should also be possible.

This is my try:

Code: Pascal  [Select][+][-]
  1. function TStrings2String(TS: TStrings): String;
  2. var i, j: Integer;
  3.     s: String;
  4. begin
  5.   s := '';
  6.   j := TS.Count - 1;
  7.   for i:=0 to j do begin
  8.     s := s + TS[i] + #13#10;
  9.   end;
  10.   exit(s);
  11. end;
  12.  
  13. function String2TStrings(S: String): TStrings;
  14. var sr: TStringArray;
  15.     ts: TStrings;
  16.     i, j: Integer;
  17. begin
  18.   sr := s.Split(#13#10);
  19.   j := Length(sr) - 1;
  20.   for i := 0 to j do begin
  21.     ts.Add(sr[i]);
  22.   end;
  23.   exit(ts);
  24. end;
  25.  

Which unfortunately does not work. Anyone sees the error(s) in it? ;)

Thx,
--Dietmar
Lazarus 2.2.0RC1 with FPC 3.2.2 (32 Bit) on Windows10 (64Bit)

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 9589
  • FPC developer.
Re: TStrings to String and vice versa
« Reply #1 on: September 28, 2021, 02:46:14 pm »
Just assign and read from the .text property ?

Thaddy

  • Hero Member
  • *****
  • Posts: 10929
Re: TStrings to String and vice versa
« Reply #2 on: September 28, 2021, 02:57:55 pm »
Marco means this :
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}
  2. uses classes;
  3. var
  4.   s:Tstrings;
  5.   r:string;
  6. begin
  7.   s:=Tstringlist.create;
  8.   try
  9.     s.add('1');
  10.     s.add('two');
  11.     s.add('one more');
  12.     r:=s.text;  // all you need
  13.   finally
  14.     s.free;
  15.   end;
  16.   writeln(r); // proof. At this point the list itself doesn't exist anymore.
  17. end.
The other way around works the same: Assign a string (may contain linebreaks) to the text poperty of a TStrings.

This is all because TMemo.Lines is a TStrings.
« Last Edit: September 28, 2021, 03:01:35 pm by Thaddy »
The average programmer productivity is 4-5 hours per day. Peak performance 72 hours for short bursts. MTBF is 1 second or less.

dietmar

  • Full Member
  • ***
  • Posts: 170
Re: TStrings to String and vice versa
« Reply #3 on: September 28, 2021, 06:25:14 pm »
My TStrings2String now does

Code: Pascal  [Select][+][-]
  1. begin
  2.   ts.Text := s;
  3.   exit(ts);
  4. end;
  5.  

But that throws an exception when trying to restore the VARCHAR to the memo:

Code: Pascal  [Select][+][-]
  1.   ts:=Tstringlist.create;
  2.   ts := String2TStrings(Edit1.Text);
  3.   for i:=0 to ts.count-1 do
  4.   memo1.lines.add (ts[i]);
  5.   ts.free;
  6.  

Do I have to create ts as a new stringlist?

--Dietmar
Lazarus 2.2.0RC1 with FPC 3.2.2 (32 Bit) on Windows10 (64Bit)

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1007
    • Lebeau Software
Re: TStrings to String and vice versa
« Reply #4 on: September 28, 2021, 07:12:55 pm »
My TStrings2String now does
...
But that throws an exception when trying to restore the VARCHAR to the memo
...
Do I have to create ts as a new stringlist?

Try this:

Code: Pascal  [Select][+][-]
  1. function TStrings2String(TS: TStrings): String;
  2. begin
  3.   Result := TS.Text;
  4. end;
  5.      
  6. function String2TStrings(const S: String): TStrings;
  7. begin
  8.   Result := TStringList.Create;
  9.   try
  10.     Result.Text := s;
  11.   except
  12.     Result.Free;
  13.     raise;
  14.   end;
  15. end;
  16.  
  17. ...
  18.  
  19. //Edit1.Text := Memo1.Lines.Text;
  20. Edit1.Text := TStrings2String(Memo1.Lines);
  21.  
  22. ...
  23.  
  24. //Memo1.Lines.Text := Edit1.Text;
  25. ts := String2TStrings(Edit1.Text);
  26. try
  27.   Memo1.Lines.AddStrings(ts);
  28. finally
  29.   ts.free;
  30. end;
  31.  

That being said, it would be better if String2TStrings() takes in a target TStrings instead of returning a new one, eg:

Code: Pascal  [Select][+][-]
  1. function TStrings2String(TS: TStrings): String;
  2. begin
  3.   Result := TS.Text;
  4. end;
  5.      
  6. procedure String2TStrings(const S: String; Strs: TStrings);
  7. var
  8.   sl: TStringList;
  9. begin
  10.   sl := TStringList.Create;
  11.   try
  12.     sl.Text := s;
  13.     Strs.AddStrings(sl);
  14.   finally
  15.     sl.Free;
  16.   end;
  17. end;
  18.  
  19. ...
  20.  
  21. Edit1.Text := TStrings2String(Memo1.Lines);
  22. ...
  23. String2TStrings(Edit1.Text, Memo1.Lines);
  24.  
« Last Edit: September 28, 2021, 07:14:59 pm by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

Thaddy

  • Hero Member
  • *****
  • Posts: 10929
Re: TStrings to String and vice versa
« Reply #5 on: September 28, 2021, 07:19:31 pm »
Should this function parameter not also be const declared because of refcount issues?
Code: Pascal  [Select][+][-]
  1. function TStrings2String(const TS: TStrings): String;
  2. begin
  3.   Result := TS.Text;
  4. end;
The average programmer productivity is 4-5 hours per day. Peak performance 72 hours for short bursts. MTBF is 1 second or less.

dietmar

  • Full Member
  • ***
  • Posts: 170
Re: TStrings to String and vice versa
« Reply #6 on: September 28, 2021, 07:30:49 pm »
@Remy: Now I am confused. Should I use the first or the second code?
And if the second, should'nt it be "Var strs..." in the declaration, because the variable gets modified?

Thx!

--Dietmar
Lazarus 2.2.0RC1 with FPC 3.2.2 (32 Bit) on Windows10 (64Bit)

Thaddy

  • Hero Member
  • *****
  • Posts: 10929
Re: TStrings to String and vice versa
« Reply #7 on: September 28, 2021, 09:45:44 pm »
You should use his code or mine, but with the provision I added in my last post.
Either code should provide you with enough knowledge to implement.
The average programmer productivity is 4-5 hours per day. Peak performance 72 hours for short bursts. MTBF is 1 second or less.

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1007
    • Lebeau Software
Re: TStrings to String and vice versa
« Reply #8 on: September 29, 2021, 01:04:35 am »
Should this function parameter not also be const declared because of refcount issues?

No, because objects are not reference-counted.  Strings are, interfaces are, but objects are not.

Now I am confused. Should I use the first or the second code?

Use whichever one suits your needs.

However, most devs feel that having a function return a new dynamically-allocated object that the caller is expected to free is not a good design choice.  The caller should create its own object however it wants, and then the function should merely populate that object with data as needed.  The caller can then decide what to do with the object afterwards.  But design is more of a personal choice.

Personally, I wouldn't even bother using such simple functions.  They don't really add much value to code (especially TStrings2String()).  If a caller already has access to a TStrings object, it could just read the Text property directly, and assign the Text property directly.

And if the second, should'nt it be "Var strs..." in the declaration, because the variable gets modified?

No, because the function is not modifying the passed pointer itself to point at a different object.  It is modifying the contents of the object that is being pointed at.  Two different scenarios.
« Last Edit: September 29, 2021, 01:10:11 am by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

egsuh

  • Hero Member
  • *****
  • Posts: 854
Re: TStrings to String and vice versa
« Reply #9 on: September 29, 2021, 04:21:07 am »
Code: Pascal  [Select][+][-]
  1.  ts:=Tstringlist.create;
  2.   ts := String2TStrings(Edit1.Text);
  3.   for i:=0 to ts.count-1 do
  4.   memo1.lines.add (ts[i]);
  5.   ts.free;

You only have to do :

memo1.lines.text := Edit1.Text;

For the reverse, 
Edit1.Text:= Memo1.lines.text; 
« Last Edit: September 29, 2021, 04:24:03 am by egsuh »

PascalDragon

  • Hero Member
  • *****
  • Posts: 3398
  • Compiler Developer
Re: TStrings to String and vice versa
« Reply #10 on: September 29, 2021, 08:55:40 am »
Should this function parameter not also be const declared because of refcount issues?

As Remy Lebeau wrote classes are not references counted, so const or not makes no difference in that regard.

dietmar

  • Full Member
  • ***
  • Posts: 170
Re: TStrings to String and vice versa
« Reply #11 on: September 29, 2021, 10:40:03 am »
Thank you all for the patient explanations!

--Dietmar
Lazarus 2.2.0RC1 with FPC 3.2.2 (32 Bit) on Windows10 (64Bit)

Thaddy

  • Hero Member
  • *****
  • Posts: 10929
Re: TStrings to String and vice versa
« Reply #12 on: September 29, 2021, 10:47:05 am »
Should this function parameter not also be const declared because of refcount issues?

As Remy Lebeau wrote classes are not references counted, so const or not makes no difference in that regard.
TStrings has at least an interface in its inheritance through Tpersistent. IInterface is refcounted by default? Unless corba. Or is interface free from IInterface? Then I misunderstood. Anyway it does not hurt to declare as const.
« Last Edit: September 29, 2021, 10:54:29 am by Thaddy »
The average programmer productivity is 4-5 hours per day. Peak performance 72 hours for short bursts. MTBF is 1 second or less.

PascalDragon

  • Hero Member
  • *****
  • Posts: 3398
  • Compiler Developer
Re: TStrings to String and vice versa
« Reply #13 on: September 29, 2021, 01:26:54 pm »
Should this function parameter not also be const declared because of refcount issues?

As Remy Lebeau wrote classes are not references counted, so const or not makes no difference in that regard.
TStrings has at least an interface in its inheritance through Tpersistent. IInterface is refcounted by default? Unless corba. Or is interface free from IInterface? Then I misunderstood. Anyway it does not hurt to declare as const.

The reference counting of interfaces only applies if you have an interface reference. If you use the class reference then there is no reference counting. This is after all the reason why the warning "only work with interface references and not the class reference when working with interfaces" is so important.

Thaddy

  • Hero Member
  • *****
  • Posts: 10929
Re: TStrings to String and vice versa
« Reply #14 on: September 29, 2021, 01:33:59 pm »
Yup Sarah, I misunderstood. Tnx for the explanation.
The average programmer productivity is 4-5 hours per day. Peak performance 72 hours for short bursts. MTBF is 1 second or less.

 

TinyPortal © 2005-2018