Wyjątki - jeden na cały program

0

Przeczytałem artykuł dotyczący wyjątków na tej stronie, lecz niestety nie udało mi się go do końca ogarnąć. Mam oto taki problem. Stworzyłem przykładowo program w którym jest dajmy na to 40 poleceń readln oczekujących na podanie liczby. Oczywiście po podaniu jakiejkolwiek litery program padnie. I tu następuje moje pytanie - czy istnieje możliwość stworzenia jednego fragmentu kodu obsługującego ten wyjątek dla całego programu, a nie tworzyć dla każdego z tych 40 readln z osobna?

1

Jeżeli wszystkie procedury Readln mają wczytywać liczbę tego samego typu, to bez problemu możesz sobie napisać funkcję, która będzie to obsługiwała; Tylko żeby program nie został przerwany po podaniu czegoś innego niż liczby, trzeba wyłączyć obsługę błędów wejścia/wyjścia dyrektywą $IOCHECKS; A żeby sprawdzić czy pobranie liczby z klawiatury powiodło się, można wykorzystać funkcję IOResult;

Przykład takiej funkcji poniżej:

{$IOCHECKS OFF}

function GetNumber(out ANumber: Integer): Boolean;
begin
  ReadLn(ANumber);
  Result := IOResult() = 0;
end;

var
  intNumber: Integer;
begin
  Write('Podaj liczbe: ');

  if GetNumber(intNumber) then
    Write('podano liczbe ', intNumber)
  else
    Write('nie podano poprawnie liczby');

  ReadLn;
end.

Dzięki temu program nie wyłaczy się (ani nie zatrzyma w trybie debug), jeśli podamy nieprawidłową liczbę;

Inny sposób to pobieranie łańcucha a nie liczby i wypróbowanie konwersji łańcucha na liczbę, np. za pomocą funkcji TryStrToInt:

uses
  SysUtils;

function GetNumber(out ANumber: Integer): Boolean;
var
  strInput: AnsiString;
begin
  ReadLn(strInput);
  Result := TryStrToInt(strInput, ANumber);
end;

var
  intNumber: Integer;
begin
  Write('Podaj liczbe: ');

  if GetNumber(intNumber) then
    Write('podano liczbe ', intNumber)
  else
    Write('nie podano poprawnej liczby');

  ReadLn;
end.

I też będzie działać bez przerywania czy innych cudów.

0

Ok, a gdybym chciał powtórzyć wpisywanie liczby? I czy można to zrobić dla liczb rzeczywistych? Czyli na zasadzie: wprowadź liczbę-> wpisano litery -> powtórz wprowadzania liczby aż do skutku. Wyglądałoby to tak?

{$IOCHECKS OFF}
 
function GetNumber(out ANumber: real): Boolean;
begin
  ReadLn(ANumber);
  Result := IOResult() = 0;
end;

procedure podajliczbe(rNumber); 
begin
   GetNumber(rNumber);
    Write('podano liczbe ', rNumber)
  else
  begin
    Write('nie podano poprawnie liczby');
    GetNumber(rNumber);
  end;
end; 

var
  rNumber: real;
begin
  Write('Podaj liczbe: ');
 
  podajliczbe;
 
  ReadLn;
end.

dodanie znacznika <code class="delphi"> - @furious programming

1

Jeśli chcesz wpisywać liczbę do skutku, to możesz to zrobić np. tak:

{$IOCHECKS OFF}

procedure GetNumber(const AMessage: AnsiString; out ANumber: Double);
begin
  repeat
    Write(AMessage);
    ReadLn(ANumber);
  until IOResult() = 0;
end;

var
  dblNumber: Double;
begin
  GetNumber('Podaj liczbe: ', dblNumber);
  Write('Podana liczba: ', dblNumber:2:2);
  ReadLn;
end.

Tylko pamiętaj, że w ten sposób wprowadzana liczba z klawiatury obsługuje znak . jako separator dziesiętny.

1 użytkowników online, w tym zalogowanych: 0, gości: 1