[Pascal]Pętla powrotu do menu programu

Witam, napisałem sobie kalkulator, definiując każde działanie jako procedurę z menu do którego wykorzystałem instrukcję case. Chciałem zrobić taki myk, żeby po zakończeniu procedury np. dodawania program wyświetlał komunikat informujący, żeby wciśnąć q aby wyjść z programu, lub m aby wrócić do menu . Wpadłem więc na pomysł, żeby stworzyć procedurę koniec z tym właśnie napisałem i instrukcją warunkową, którą objąłem pętlą repeat. Kod mojego programu wygląda tak:

wynik:extended;

stopien:integer;


PROCEDURE dodawanie;

begin

write('Podaj pierwszą liczbę: ');

read(liczba1);

write('Podaj drugą liczbę: ');

read(liczba2);

suma:=liczba1+liczba2;

writeln('Wynik dodawania wynosi: ' ,suma:0:3);

END;


PROCEDURE odejmowanie;

begin

write('Podaj pierwszą liczbę: ');

read(liczba1);

write('Podaj drugą liczbę: ');

read(liczba2);

roznica:=liczba1-liczba2;

writeln('Wynik odejmowania wynosi: ', roznica:0:3);

END;


PROCEDURE mnozenie;

begin

write('Podaj pierwszą liczbę: ');

read(liczba1);

write('Podaj drugą liczbę: ');

read(liczba2);

iloczyn:=liczba1*liczba2;

writeln('Wynik wnożenia wynosi: ', iloczyn:0:0);

END;


PROCEDURE dzielenie;

begin

write('Podaj pierwszą liczbę: ');

read(liczba1);

write('Podaj drugą liczbę: ');

read(liczba2);

iloraz:=liczba1/liczba2;

writeln('Wynik dzielenia wynosi: ', iloraz:0:3);

END;


PROCEDURE pierwiastek;

begin

write('Podaj stopień pierwiastka: ');

read(stopien);

write('Podaj liczbę pod pierwiastkiem: ');

read(liczba);

IF (liczba>0)and(stopien>0) THEN

pierw:=Exp((1/stopien)*Ln(liczba))else pierw:=0;

writeln('Pierwiastek: ' ,stopien , 'stopnia z liczby ' ,liczba:0:0 , 'wynosi: ' , pierw:0:0);

END;


PROCEDURE potegowanie;

BEGIN

write('Podaj podstawę potęgi: ');

read(x);

writeln('Podaj potęge: ');

read(y);

wynik:=1;

for i:=1 to y do wynik:=wynik*x;

writeln('Wynik potęgowania wynosi: ' ,wynik:0:0);

END;


PROCEDURE MENU;

BEGIN

clrscr;

GOTOXY(20,1); writeln(' ****KALKULATOR****');

writeln('Jakie działanie chcesz wykonać?');

writeln('1.dodawanie');

writeln('2.odejmowanie');

writeln('3.mnożenie');

writeln('4.dzielenie');

writeln('5.pierwiastkowanie');

writeln('6.potęgowanie');

read(odp);


CASE odp OF

1:dodawanie;

2:odejmowanie;

3:mnozenie;

4:dzielenie;

5:pierwiastek;

6:potegowanie;


ELSE writeln('Zły wybór');

END;

END;





PROCEDURE koniec;

begin

repeat

writeln('Aby wyjść z programu wciśnij q. Aby wrócić do menu wciśnij m');

read(o);

IF o='q' THEN halt;

IF o='m' THEN menu;

until odp=6

END;


BEGIN

clrscr;

menu;

koniec;

readkey;

END.

Problem polega na tym, że owszem, procedura działa, ale jednak nie do końca, ponieważ jeżeli wybiorę w menu 1, czyli dodawanie, to po wyniku wyświetla mi 3 razy napis Wciśnij q aby wyjść z programu, lub wciśnij m aby wrócić do menu. W przypadku pozostałych działań problem ten nie występuje. Co jest nie tak z tym programem, że tak się dzieje?

Dodane 13.04.2011 (Śr) 0:28

Jeszcze byłbym bardzo wdzięczny, jeżeli ktoś podpowiedziałby mi co zrobić aby przy wybieraniu opcji w menu i po wciśnięciu q lub m nie trzeba było dawać entera.

  1. Do wczytywania danych z klawiatury nie używaj Read, tylko Readln

  2. Dodane

    o:= Readkey;

Mógłbym prosić o wytłumaczenie dlaczego readln, a nie read, ponieważ jeszcze nie znam się za dobrze na Pascalu, bo dopiero się go uczę a ja jestem właśnie taki, że lubię wiedzieć dlaczego tak a nie inaczej…

Dodane 13.04.2011 (Śr) 8:06

No i guzik, jak dodałem o:=readkey, to i tak muszę zatwierdzać enterem… :confused:

  1. Jeśli wczytujesz dane z klawiatury (np liczbę, która może składać się z kilku cyfr), to program wczytuje kolejne znaki do momentu, gdy zostanie naciśnięty klawisz Enter, który oznacza koniec wczytywania. Instrukcja Read pobiera z bufora klawiatury tylko wczytane znaki, kod klawisza Enter nadal znajduje się w buforze klawiatury, co powoduje późniejsze problemy w działaniu programu. Instrukcja Readln z kolei pobiera zarówno wczytane znaki jak i kod klawisza Enter. Można napisać, że ReadLn = Read Line, czyli wczytaj dane i przejdź do następnej linii (instrukcja Read tego nie robi)

Instrukcja Read służy natomiast do wczytywania danych z plików, zwłaszcza plików zdefiniowanych

  1. Nie wiem, czy mnie dobrze zrozumiałeś (właściwie, to mogłem to od razu napisać), ale powinieneś to wpisać zamiast Read(o), a nie dodać

Aha, bardzo dziękuję Ci za wyjaśnienie wszystkiego… Co do tego readkey’a, to właśnie nie zrozumiałem i zamiast wywalić read(o), to dopisałem nad nim o:=readkey…