Ir para o conteúdo

Leitura segura de dados

Já aconteceu estarmos a querer ler um número e o utilizador introduz um valor alfanumérico. Resultado: o programa crasha.

Podemos tratar a excepção com uma estrutura try-except. No entanto, não acho propriamente elegante.

Portanto, deixo aqui um pequeno excerto de uma unit que tenho implementada há c'anos. A partir desta amostra poderão acrescentar com muito mais tipos de dados e novas funcionalidades.

Aqui fica o código da unit e do programa de teste:

Unit

{$mode objfpc}
unit USecRead;

interface
uses sysutils;

type TSecureRead = class(TObject)
     private
        var vErrorPos : word;

     public
        function TLongint(const PROMPT : string; var i : longint) : boolean;
        function TReal(const PROMPT : string; var r : real) : boolean;
        property ErrorPos : word read vErrorPos;
     end;

var SecureRead : TSecureRead;


implementation

function TSecureRead.TLongint(const PROMPT : string; var i : longint) : boolean;
var s : string;
    e : word;
begin
    Write(PROMPT);
    ReadLn(s);
    Val(s, i, e);
    TLongint := (e = 0);
    self.vErrorPos := e;
end;


function TSecureRead.TReal(const PROMPT : string; var r : real) : boolean;
   // DIY :D
end;


initialization
    SecureRead := TSecureRead.Create;

finalization
    SecureRead.Free;

end.

Programa de teste

program USecRead_test;
uses USecRead;

const CRLF = #13+#10;
var n : longint;

begin
    repeat
        while not SecureRead.TLongint('n? ', n) do
            WriteLn('[KO] Nao foi lido um Longint!', CRLF,
                    '   * Erro na posicao ', SecureRead.ErrorPos, CRLF,
                    '   * Por curiosiade, n=', n, CRLF);

        Writeln('[OK] Longint lido correctamente!', CRLF,
                '   * n=', n);
    until n=0;
end.

Resultado final

Teste realizado no Ubuntu.

$ ./USecRead_test
n? 123e5
[KO] Nao foi lido um Longint!
   * Erro na posicao 4
   * Por curiosiade, n=0

n? 12345
[OK] Longint lido correctamente!
   * n=12345
n? 0
[OK] Longint lido correctamente!
   * n=0
$