Fenner
Biblioteca

Texto e coleções

Saída formatada, Format, e as coleções mais usadas — listas, dicionários e listas de cadeias.

Escrevendo na saída#

Write e WriteLn aceitam qualquer número de argumentos de tipos variados e imprimem cada um na sua forma natural. Um booleano sai como TRUE/FALSE, e um real em formato curto. A largura e as casas vêm no estilo do Pascal, com :largura:casas:

text-output.fxp
program TextOutput;

var
  Pi: Float64;
begin
  Pi := 3.14159265;

  WriteLn(Pi);                 // formato curto
  WriteLn(Pi:0:2);             // largura:casas, como no Pascal
  WriteLn(Pi:10:3, '|');
  WriteLn(42:6, '|', 'ab':5, '|');

  // Format recebe um "array of const"
  WriteLn(Format('%s tem %d itens e %8.2f de saldo', ['lista', 3, Pi]));
  WriteLn(Format('%-6s|%6s|%x|%%', ['ab', 'cd', 255]));
end.
Saída
3.14159
3.14
     3.142|
    42|   ab|
lista tem 3 itens e     3.14 de saldo
ab    |    cd|ff|%

Format#

Format recebe uma cadeia de formato e um array of const (os valores entre colchetes). Os especificadores aceitos são %s %c %d %i %u %x %X %f %e %g e %%, com largura e precisão opcionais (%8.2f, %-6s).

Um especificador desconhecido, um argumento a menos ou a mais, ou um tipo errado são exceção, não silêncio: um formato escrito errado viraria texto errado longe de onde foi escrito.

Conversões#

As conversões entre número e texto dizem qual cadeia entra e sai (veja as convenções):

Fenner
S := IntToUStr(42);                  // Int → UString
N := UStrToInt32(S);                 // UString → Int32 (levanta se não for número)
N := UStrToInt32Def(S, 0);           // com padrão, sem exceção

Estão disponíveis também Copy, Pos, Delete, Insert, Length, Trim, TrimLeft, TrimRight, SameText e as dezenas de funções de texto da RTL, em versões para as cadeias de bytes e para UString.

Coleções#

Na BedRock (uses System.Remainder), as coleções seguem os nomes do Delphi:

containers.fxp
program Containers;

uses
  System.Remainder;

var
  Numbers: TList<Int32>;
  Ages: TDictionary<UString, Int32>;
  Lines: TStringList;
  Age, I: Int32;
  Builder: TStringBuilder;
begin
  // lista genérica
  Numbers := TList<Int32>.Create;
  Numbers.Add(30);
  Numbers.Add(10);
  Numbers.Add(20);
  Numbers.Delete(1);          // tira o 10
  for I := 0 to Numbers.Count - 1 do
    Write(Numbers[I], ' ');
  WriteLn;

  // dicionário genérico
  Ages := TDictionary<UString, Int32>.Create;
  Ages.Add('Ana', 31);
  Ages.Add('Bia', 27);
  if Ages.TryGetValue('Ana', Age) then
    WriteLn('Ana tem ', Age);
  WriteLn('tem Caio? ', Ages.ContainsKey('Caio'));

  // lista de cadeias, com ordenação
  Lines := TStringList.Create;
  Lines.Add('banana');
  Lines.Add('abacaxi');
  Lines.Add('caju');
  Lines.Sort;
  WriteLn(Lines.Count, ' linhas, a primeira é ', Lines[0]);

  Builder := TStringBuilder.Create;
  Builder.Append('montagem ');
  Builder.Append('linear');
  WriteLn(Builder.ToString);
end.
Saída
30 20 
Ana tem 31
tem Caio? FALSE
3 linhas, a primeira é abacaxi
montagem linear
TipoPara quê
TList<T>lista genérica (Add, Delete, Count, indexação)
TDictionary<K,V>dicionário (Add, TryGetValue, ContainsKey, Remove)
TStringListlista de cadeias, com Sort e acesso por índice
TStringBuildermontagem linear de texto (concatenar num laço com + é quadrático)

A RTL do compilador traz outras formas, mais enxutas: TRList<T> e TRDict<K,V> são records que nascem zerados, sem Create (um var L: TRList<Int32>; já é uma lista vazia pronta para Add), e TLStringBuilder monta cadeias de bytes. São os blocos que o próprio compilador usa.

Arquivos e fluxos#

TFileStream, TMemoryStream e TStringStream leem e escrevem fluxos; TDirectory e as rotinas de arquivo da RTL cuidam de pastas e nomes; e a RTL do compilador traz TFile.ReadAllText/WriteAllText para o caso de arquivo inteiro. Textos de código-fonte e de .ll são bytes UTF-8 (LString): quem quiser UString converte na borda.