Pascal kontrola błędów fatalnych

0

Witam, czy jest możliwość obsługi/kontroli błędów fatalnych takich jak error 201? z błędami wejscia/wyjścia sobie radzę. Chcę zabezpieczyć program przed jego wyłączeniem. Pozdrawiam

0

range check error (201) to nie fatal error, a w aplikacji pod windows nie zamyka programu.

0

chyba {$r+/-

0

Właśnie zamyka, używam free pascala. Ogólnie jest to w momencie gdy program czeka na wpisanie dużej litery a otrzymuje coś innego. Zmienna w którą wpisuje jest jako string.

Edit: Xitami, ale później IOresult czy coś innego?

Edit: Hmm, ja wiem co mam wpisać i kiedy wyskoczy błąd, ale chodzi o ludzi co będą go używać i wpiszą byle co i im wywali ten oto błąd.

0
rachuba21 napisał(a):

Edit: Hmm, ja wiem co mam wpisać i kiedy wyskoczy błąd, ale chodzi o ludzi co będą go używać i wpiszą byle co i im wywali ten oto błąd.

waliduj wprowadzane przez usera dane.

0

Może chodzi o konstrukcję try...except?

0
{program tlumaczy liczby rzymskie na arabskie}
{uwaga: podawaj liczby w prawidlowych formatach}
program TranslateRomanToArabic;
{crt potrzebne do keypressed - patrz przedostatnia linijka}
uses crt;

{tablica aTransTable umozliwia konwersje poszczegolnych czlonow wyrazenia}
{uwaga - wazna jest kolejnosc rekordow w tablicy!}
const
 aTransTable: array[1..13] of record
   AN: word;
   RN: string[2];
 end = ((AN: 1000; RN:'M'),  (AN: 900; RN: 'CM'), (AN: 500; RN: 'D'),
        (AN: 400; RN: 'CD'), (AN: 100; RN: 'C'),  (AN: 90; RN: 'XC'),
        (AN: 50; RN: 'L'),   (AN: 40; RN: 'XL'),  (AN: 10; RN: 'X'),
        (AN: 9; RN: 'IX'),   (AN: 5; RN: 'V'),    (AN: 4; RN: 'IV'),
        (AN: 1; RN: 'I'));


var
 RomanNumeral: string;
 ArabianNumber: longint;

 CurrNum: byte;

 CurrSymb: string[2];
 CurrVal: word;
begin
 {glowna petla}
 repeat begin

   {wczytujemy co trzeba}
   Write('Input Roman Numeral: ');
   ReadLn(RomanNumeral);

   {tlumaczenie}
   ArabianNumber := 0;
   CurrNum := 1;
   repeat
     CurrSymb := aTransTable[CurrNum].RN;
     CurrVal := aTransTable[CurrNum].AN;

     {bierzemy poczatek liczby rzymskiej i porownujemy kolejno z elementami tablicy konwersji}
     while Copy(RomanNumeral, 1, Length(CurrSymb)) = CurrSymb do
     {znalezlismy pasujacy element - dodajemy odpowiednia wartosc do liczby arabskiej i skracamy liczbe rzymska}
     begin
       Inc(ArabianNumber, CurrVal);
       Delete(RomanNumeral, 1, Length(CurrSymb));
     end;

     Inc(CurrNum);
   until RomanNumeral = '';
   {koniec liczby rzymskiej - koniec tlumaczenia}

   WriteLn('Arabian Number: ', ArabianNumber);
   WriteLn('Press ESC to quit, any other key to continue.');
   repeat until keypressed;
 end;
 {cos wcisnieto - sprawdzamy czy ESC. Jesli ESC, to konczymy, a jesli co innego, to wracamy na poczatek.}
 until readkey=Chr(27);
end. 

Jak tu validować RomanNummmeral ?

0

Jak tu validować RomanNummmeral ?

Wyjątki

0

Dobra kapuje, ale mam starego free pascala bo tylko stary mi działa na win 7 i możliwe, że nie działają te procedury na nim bo wywala mi, że zmienna try nie została znaleziona.

0

ale mam starego free pascala bo tylko stary mi działa na win 7

Pobierz Lazarusa (lepsze GUI na FPC, działa też na tym na czym FPC IDE nie działa).
a żeby działały wyjątki na starych projektach:
Na początku (za program, przed uses) daj {$mode objfpc} i dodaj do uses moduł sysutils.

0
 program KonwerterAdoRiRdoA;
{$mode objfpc}
uses crt;
var
 b:byte;
 rzymskie: string;
 arabskie: longint;
 liczba: byte;
 symbol: string[2];
 wartosc: word;
const
  atabela: array[1..13] of record
    AN: word;
    RN: string[2];
  end = ((AN: 1000; RN:'M'),  (AN: 900; RN: 'CM'), (AN: 500; RN: 'D'),
         (AN: 400; RN: 'CD'), (AN: 100; RN: 'C'),  (AN: 90; RN: 'XC'),
         (AN: 50; RN: 'L'),   (AN: 40; RN: 'XL'),  (AN: 10; RN: 'X'),
         (AN: 9; RN: 'IX'),   (AN: 5; RN: 'V'),    (AN: 4; RN: 'IV'),
         (AN: 1; RN: 'I'));
         {przyporzadkowujemy liczbie rzymskiej arabska}
label error;
begin

repeat  {gowna petla}
clrscr;
writeln('Wybierz jedna opcje:'+#10#13+ '1. Zamiana liczby Arabskiej na Rzymska.'+#10#13+'2. Zamiana liczby Rzymskiej na Arabska.'+#10#13+'3.Wyjscie');
{$I-}
readln(b);
{$I+}
if IOResult<>0 then goto error;
case (b) of
1:
begin  {arabskie na rzymskie}
    rzymskie:='';
    write('Wpisz liczbe arabska: ');
   {$I-}
  readln(arabskie);
    {$I+}
    if IOResult<>0 then goto error;

    repeat
      if arabskie-1000 >= 0 then begin
        arabskie:=arabskie-1000;
        rzymskie:=rzymskie+'M';
      end
      else if arabskie-900 >= 0 then begin
        arabskie:=arabskie-900;
        rzymskie:=rzymskie+'CM';
      end
      else if arabskie-500 >= 0 then begin
        arabskie:=arabskie-500;
        rzymskie:=rzymskie+'D';
      end
      else if arabskie-400 >= 0 then begin
        arabskie:=arabskie-400;
        rzymskie:=rzymskie+'CD';
      end
      else if arabskie-100 >= 0 then begin
        arabskie:=arabskie-100;
        rzymskie:=rzymskie+'C';
      end
      else if arabskie-90 >= 0 then begin
        arabskie:=arabskie-90;
        rzymskie:=rzymskie+'XC';
      end
      else if arabskie-50 >= 0 then begin
        arabskie:=arabskie-50;
        rzymskie:=rzymskie+'L';
      end
      else if arabskie-40 >= 0 then begin
        arabskie:=arabskie-40;
        rzymskie:=rzymskie+'XL';
      end
      else if arabskie-10 >= 0 then begin
        arabskie:=arabskie-10;
        rzymskie:=rzymskie+'X';
      end
      else if arabskie-9 >= 0 then begin
        arabskie:=arabskie-9;
        rzymskie:=rzymskie+'IX';
      end
      else if arabskie-5 >= 0 then begin
        arabskie:=arabskie-5;
        rzymskie:=rzymskie+'V';
      end
      else if arabskie-4 >= 0 then begin
        arabskie:=arabskie-4;
        rzymskie:=rzymskie+'IV';
      end
      else if arabskie-1 >= 0 then begin
        arabskie:=arabskie-1;
        rzymskie:=rzymskie+'I';
      end
    until arabskie=0;
    writeln('Liczba Rzymska: ', rzymskie );
    writeln('Nacisnij dowolny klawisz by wrocic do menu.');
    readln;
 end;

2:
 begin
    {rzymskie na arabskie}
    write('Wpisz liczbe rzymska: ');
    begin
     try
      readln(rzymskie);

    arabskie := 0;
    liczba := 1;
    repeat
      symbol := atabela[liczba].RN;
      wartosc := atabela[liczba].AN;

      {bierzemy poczatek liczby rzymskiej i porownujemy kolejno z elementami tablicy atablica}
      while copy(rzymskie, 1, length(symbol)) = symbol do
      {znalezlismy pasujacy element - dodajemy odpowiednia wartosc do liczby arabskiej i skracamy liczbe rzymska}
      begin
        inc(arabskie, wartosc);
        delete(rzymskie, 1, length(symbol));
      end;

      inc(liczba);
    until rzymskie = '';
    {koniec liczby rzymskiej}

    writeln('Liczba arabska: ', arabskie);
    writeln('Nacisnij dowolny klawisz by wrocic do menu.');
    readln;
    except
     b:=4;
     end;
    end;
end;
3: halt;

else
error:
 writeln('Zly wybor, nacisnij klawisz enter by wybrac ponownie.');
  repeat until keypressed and (readkey= #13);
 end;
 until b=3;
end.

To jest ten program, wszystko już prawie działa oprócz tego, że jak wpiszę złą wartość to nie pokazuje komentarze z else na samym dole tylko od razu czyści ekran i pokazuje menu.

0

To jest ten program, wszystko już prawie działa oprócz tego, że jak wpiszę złą wartość to nie pokazuje komentarze z else na samym dole tylko od razu czyści ekran i pokazuje menu.

Bo tak nie działa instrukcja case. Gdy już coś się wybrało to inne się nie wybierze. Czytaj dokładniej tutoriale ;) .

I NIE UŻYWAJ INSTRUKCJI GOTO W TAKIM PRZYPADKU. To się prosi o PROCEDURĘ.

0

wiem, że nie działa tak case, ale goto też tam nie wrzucę:P Okey poczytam o procedurach.

edit: dobra działa mi ten program teraz ale nie rozumiem jednej rzeczy

Procedura zostaje wywołana co się dzieje po procedurze? Bo w niej jest tylko wyświetlenie i czekanie na enter, dlaczego program uruchamia się od nowa?

0

edit: A jak w procedurze, mam dać, że wystąpił błąd i ma wrócić znów do menu?

Ja tutaj widzę dwa całkiem dobre wyjścia:

  1. Wrzucić te wybory z case w procedury też, a potem dawać if IOResult<>0 then begin ShowError;exit;end;
  2. Użyć wyjątków, z tym że tym razem można je też rzucać (poczytaj w googlach) i łapać na całe case żeby następnie wyświetlać komunikat błędu z tego wyjątku (jeżeli chcesz tego użyć to dodaj sysutils do uses).

Chyba najłatwiej tobie będzie użyć pierwszego sposobu, poprawi on też czytelność twojego kodu.

A i tak przy okazji to nie wiem po co wszystkie operacje wejścia dajesz w IOResult, ja tego tylko używam przy otwieraniu plików... W takim wypadku chyba lepiej niż wszędzie dawać sprawdzanie IOResult lepiej już użyć mechanizmu wyjątków którego celem jest właśnie zmniejszenie ilości i rozproszenia kodu odpowiedzialnego za obsługę błędów. Ale moim zdaniem w ogóle sprawdzanie wszystkich operacji wejścia/wyjścia jest bez sensu.

0

Hmm. Można trochę jaśniej na przykładach?:)

0

Procedura zostaje wywołana co się dzieje po procedurze? Bo w niej jest tylko wyświetlenie i czekanie na enter, dlaczego program uruchamia się od nowa?

Bardzo się cieszę że pytasz a nie błądzisz, ale naprawdę zamiast nas zasypywać pytaniami powinieneś poeksperymentować poszukać więcej. W każdym razie po procedurze następuje powrót do procedury która ją wywołała. Twój program nie uruchamia się od nowa, najprawdopodobniej po prostu coś skopałeś.

Na przyszłość: Ładniej formatuj kod, Lazarus ci w tym pomoże (jeżeli już go masz, jeżeli nie to polecam).

0

Hmm. Można trochę jaśniej na przykładach?:)

Google twoim przyjacielem, poszukaj/poeksperymentuj. Jeżeli coś ci się wydaje za trudne, to po prostu z tego póki co nie korzystaj, na wszystko przyjdzie czas.
Nie jestem tutaj aby ciebie uczyć podstaw, ani żeby rozwiązywać twoje problemy. Jestem tutaj tylko po to żeby tobie dać wskazówki jak rozwiązać dany problem, żeby pobudzić ciebie do działania dając małe wsparcie. Nie oczekuj ode mnie zbyt wielkich rzeczy. Lepiej niż pytać o wszystko na forum, pokombinuj z kompilatorem, nauczysz się wielu rzeczy.

Ja się nauczyłem programować bez korzystania z pomocy forum, uważam że wyszło mi to dobrze. Oczywiście jeżeli chcesz to korzystaj z niego, ale mądrze. Nie oczekuj od nas/ode mnie że będę tobie przez 2h tłumaczył działanie pętli itd. - eksperymentuj/szukaj. Jak już mówiłem, ja tutaj jestem tylko po to, żeby tobie wskazać drogę, a nie zastępować tutorial/kurs/googla/dokumentacje/eksperymentowanie. Masz takie ładne kursy, czemu z nich nie skorzystasz?

Tak czy siak, widzę że całkiem dobrze ci nauka, powodzenia. Mam nadzieję że następne moje wypowiedzi będą mogły już być milsze.

0

Wszytko działa pięknie, dzięki wielkie za pomoc:)

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