Step 1 of 5 · Reading · ~2 min
Learn
Strings, Procedural Types, Variants
FreePascal's SysUtils and StrUtils units cover most string needs.
SysUtils essentials
Format('%s = %d', [name, value])— printf-styleIntToStr(n),StrToInt(s),TryStrToInt(s, n)FloatToStr(x),StrToFloat(s),FormatFloat('0.00', x)UpperCase(s),LowerCase(s)Trim(s),TrimLeft(s),TrimRight(s)StringReplace(s, old, new, [rfReplaceAll, rfIgnoreCase])Concat(s1, s2, ...)
Splitting and joining
FPC 3.x adds string helpers, but only in Delphi mode — line.Split(...) in the default dialect fails with Illegal qualifier, so the {$mode delphi} line is load-bearing:
{$mode delphi}{$H+}
uses SysUtils;
var
s: string;
parts: TStringArray;
word: string;
begin
s := 'hello world foo bar';
parts := s.Split([' ']);
for word in parts do
WriteLn(word);
end.
Manual split (older code):
uses Classes;
var lines: TStringList;
begin
lines := TStringList.Create;
try
lines.Delimiter := ' ';
lines.StrictDelimiter := True;
lines.DelimitedText := s;
for i := 0 to lines.Count - 1 do
WriteLn(lines[i]);
finally
lines.Free;
end;
end.
StrUtils — extras
uses StrUtils;
DupeString('ab', 3) { 'ababab' }
LeftStr('hello', 3) { 'hel' }
RightStr('hello', 3) { 'llo' }
MidStr('hello', 2, 3) { 'ell' }
ReverseString('hello') { 'olleh' }
ContainsText(haystack, needle) { case-insensitive }
StartsText('foo', 'foo bar') { true }
Pos and PosEx
Pos('world', 'hello world') { 7 — 1-indexed }
Pos('xyz', 'hello world') { 0 — not found }
PosEx('o', 'foo', 1) { find 'o' starting at index 1 }
String concatenation in loops
Avoid s := s + chunk in a loop: each + allocates a new string and copies everything written so far, so assembling n pieces costs O(n²) bytes copied. Collect the pieces and join once. Delphi's TStringBuilder is the usual answer, but it is absent from FPC 3.0.4's RTL — here, a TStringList does the same job:
uses Classes, SysUtils;
var
parts: TStringList;
i: integer;
begin
parts := TStringList.Create;
try
for i := 1 to 1000 do
parts.Add(IntToStr(i));
WriteLn(StringReplace(parts.Text, sLineBreak, '', [rfReplaceAll]));
finally
parts.Free;
end;
end.
parts.Text is the list joined with line breaks; strip them and you have the concatenation, built with one allocation per piece instead of one copy of the whole result per piece.
Format specifiers
Format('%d items', [42]) { '42 items' }
Format('%6.2f%%', [99.5]) { ' 99.50%' }
Format('%-10s|', ['hi']) { 'hi |' (left-pad) }
Format('%s = %d', ['x', 5])
The [ ... ] is an open-array of Variant (any type). Format infers from %d, %s, %f.
Conversion best practices
uses SysUtils;
var n: integer;
begin
if TryStrToInt(input, n) then
Process(n)
else
WriteLn('invalid: ', input);
end.
TryStrToInt/TryStrToFloat return boolean instead of throwing — much nicer for input parsing.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…