Wątek przeniesiony 2017-10-17 16:36 z C/C++ przez kq.

Obsługa wyjątków

0

Cześć. Muszę zrobić zadanie/ grę. Treść brzmi tak :

Napisz grę, która będzie losowała dowolne litery z alfabetu i wyświetlał je na ekranie, a zadaniem gracza jest podać szybko odpowiadający jej kod ascii. Fragment programu odpowiedzialny za zadawanie pytań i sprawdzanie odpowiedzi użytkownika jest zamknięty w funkcji, która zwraca liczbę całkowitą – sumaryczną liczbę sekund, jakiej użytkownik potrzebował, żeby udzielać odpowiedzi na serię pytań. Może zdarzyć się, że użytkownik poda niewłaściwy kod ASCII, ale to nie powoduje przerwania gry. Dopiero w przypadku popełnienia przez użytkownika drugiej pomyłki zamiast kolejnego pytania rzucany jest wyjątek, który jest przechwycony dopiero w funkcji main. W ramach obsługi wyjątku użytkownik dostaje pytanie, czy chce spróbować jeszcze raz i jeżeli tak – funkcja zadająca pytania jest ponownie wywoływana.

Mój błąd polega na tym, że gdy program dojdzie 2 raz do wyjątku(do linijki z throw) to wywala błąd i zatrzymuje program. Kod poniżej. Z góry dzięki za pomoc.

#include <ctime>
#include <fstream>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <cstdio>

#define N 5

using namespace std;

double czas()
{
	char litery[N];
	int litera;
	srand(time(NULL));
	int i, j;
	int licznik = 0;
	time_t start, finish;


	for (i = 0; i < N; i++)
	{
		litery[i] = (char)(rand() % 24) + 65;
		j = (rand() % 2);								//litery alfabetu
		if (j)
		{
			litery[i] += (97 - 65);
		}
	}

	time(&start);
	for (int k = 0; k < N; k++)
	{

		cout << "\nWylosowana litera to: ";
		cout << litery[k] << endl;

		cout << "Prosze podac liczbe kodu ASCI odpowiadajaca literze alfabetu wyswietlanej na ekranie: ";
		cin >> litera;

		if (litera == (int)litery[k])
		{
			cout << "Podano poprawna odpowiedz.\n " << endl;
		}
		else
		{
			cout << "Podano bledna odpowiedz.\n " << endl;
			licznik++;
		}

		if (licznik == 2)
		{
			cout << "Popelniono 2 bledy. \n";
			throw licznik;
		}
	}
	time(&finish);
	double czas= difftime(finish, start);
	return czas;
}


int main()
{

	cout << "Przystepuje do testu. (Czas liczony od momentu wyswietlenia 1 litery." << endl;
	time_t actual = time(0);
	cout << "Czas: " << asctime(localtime(&actual));
	try
	{
		double wynik=0;
		wynik = czas();
		cout << "Czas gry wynosi: " << wynik << " sekund" << endl;
	}

	catch (int licznik)
		{
			cout << "Czy chcesz sprobowac jeszcze raz? ";
			double wynik=0;
			wynik = czas();
			cout << "Czas gry wynosi: " << wynik << " sekund" << endl;
		}

	return 0;
}
0

W czym konkretnie jest problem? Jeśli dobrze rozumiem zadanie, tylko jednokrotnie masz odpytać czy użytkownik chce zagrać jeszcze raz. Jeśli chcesz to robić wielokrotnie, użyj pętli do wywoływania czas() i łapania wyjątków przez tę funkcję rzucanych.

0

Program używany jest tylko raz gdy podane są 4 albo 5 poprawne odpowiedzi, a w przypadku podania 2 błędnych odpowiedzi program pyta się czy chcemy powtórzyć grę (tutaj nie dokończyłem), jeśli chcemy wykonujemy ja tylko 1 raz. Nie może to być w kółko. W grę można zagrać raz, a jak się przegra spróbować ostatni raz. Mam nadzieje że zrozumiałeś :p

0

Tak to zrozumiałem, ale w takim razie w czym jest problem?

0

Uruchamiam grę, podaje 2 błędne odpowiedzi, "wywoływany" jest wyjątek, gra zaczyna się od początku, podaje znów 2 błędne odpowiedzi i w tym momencie(powinna zakończyć się gra) wywala błąd związany z wyjątkiem.

0

A co ma się dziać? Przed chwilą napisałeś, że

Nie może to być w kółko. W grę można zagrać raz, a jak się przegra spróbować ostatni raz.

0

Wyjątek może wykonać sie tylko raz. W grę można zagrać max 2 razy. Nie czytelnie napisałem, dlatego pytałem czy mnie zrozumiałeś :D

0

Dozwolone jest wykonanie raz wyjątku a za 2 razem ma się wyłączyć gra.

0

Ale przecież tak jest. Przy drugim wywołaniu Twojego wyjątku gra się kończy!

0
karwan33 napisał(a):

Uruchamiam grę, podaje 2 błędne odpowiedzi, "wywoływany" jest wyjątek, gra zaczyna się od początku, podaje znów 2 błędne odpowiedzi i w tym momencie(powinna zakończyć się gra) wywala błąd związany z wyjątkiem.

Stworzyłbym zmienną np. int licznik_wyjatkow = 0;
Jeśli jest wywoływany wyjątek, to licznik_wyjatkow++;
I jeśli licznik_wyjatkow == 2, to exit.

0

No własnie nie kończy się i to jest błąd :/ Ciemn_ptak poszedłem w te stronę z licznikiem i coś mi też nie wychodziło. Nie mam pojęcia czemu...

0

U mnie się kończy (może nie jest pięknie, ale zgodnie z opisem):

./a.out
Przystepuje do testu. (Czas liczony od momentu wyswietlenia 1 litery.
Czas: Tue Oct 17 19:03:27 2017

Wylosowana litera to: K
Prosze podac liczbe kodu ASCI odpowiadajaca literze alfabetu wyswietlanej na ekranie: 23
Podano bledna odpowiedz.


Wylosowana litera to: N
Prosze podac liczbe kodu ASCI odpowiadajaca literze alfabetu wyswietlanej na ekranie: 23
Podano bledna odpowiedz.

Popelniono 2 bledy.
Czy chcesz sprobowac jeszcze raz?
Wylosowana litera to: S
Prosze podac liczbe kodu ASCI odpowiadajaca literze alfabetu wyswietlanej na ekranie: 23
Podano bledna odpowiedz.


Wylosowana litera to: M
Prosze podac liczbe kodu ASCI odpowiadajaca literze alfabetu wyswietlanej na ekranie: 23
Podano bledna odpowiedz.

Popelniono 2 bledy.
terminate called after throwing an instance of 'int'
zsh: abort (core dumped)  ./a.out
0

W załączniku podałem ci zdjęcie błędu jaki pojawia się w tym momencie.bład.jpg

0

Odpalasz w trybie debug, a w nim VC++ ma dodatkowe hooki na abort. Nie zmienia to faktu, że program się zakończył z błędem. Jeśli chcesz zmienić sposób zakończenia programu - postępuj zgodnie z radą o liczniku.

0

Z licznikiem dobry pomysł, ale nie wiem jak go zainicjować za każdym razem funkcja wywoływana jest od nowa i dane są resetowane. tak jakby. Możesz mi rzucić jakąś wskazówkę?

0

Przekaż go jako argument. Ba, możesz po prostu przekazać boola, czy ma rzucić wyjątek, czy wywołać std::exit.

0

#include <ctime>
#include <fstream>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <cstdio>

#define N 5

using namespace std;

double czas(int licznik_wyj)
{
	char litery[N];
	int litera;
	srand(time(NULL));
	int i, j;
	int licznik = 0;
	time_t start, finish;


	for (i = 0; i < N; i++)
	{
		litery[i] = (char)(rand() % 24) + 65;
		j = (rand() % 2);								//litery alfabetu
		if (j)
		{
			litery[i] += (97 - 65);
		}
	}

	time(&start);
	for (int k = 0; k < N; k++)
	{

		cout << "\nWylosowana litera to: ";
		cout << litery[k] << endl;

		cout << "Prosze podac liczbe kodu ASCI odpowiadajaca literze alfabetu wyswietlanej na ekranie: ";
		cin >> litera;

		if (litera == (int)litery[k])
		{
			cout << "Podano poprawna odpowiedz.\n " << endl;
		}
		else
		{
			cout << "Podano bledna odpowiedz.\n " << endl;
			licznik++;
		}


		if (licznik == 2)
		{
			cout << "Popelniono 2 bledy. \n";
			licznik_wyj++;
			if (licznik_wyj == 2)
			{
				cout << "Znów popelniles 2 bledy. Koniec gry." << endl;
				return 0;
			}
			else
				throw licznik;
		}

	}
	time(&finish);
	double czas= difftime(finish, start);
	return czas;
}


int main()
{
	int licznik_wyj = 0;
	cout << "Przystepuje do testu. (Czas liczony od momentu wyswietlenia 1 litery." << endl;
	time_t actual = time(0);
	cout << "Czas: " << asctime(localtime(&actual));
	try
	{
		double wynik=0;
		wynik = czas(licznik_wyj);
		cout << "Czas gry wynosi: " << wynik << " sekund" << endl;
	}

	catch (int licznik)
		{
			cout << "Czy chcesz sprobowac jeszcze raz? ";
			double wynik=0;
			wynik = czas(licznik_wyj);
			cout << "Czas gry wynosi: " << wynik << " sekund" << endl;
		}

	return 0;
}

no i znów to samo, dlaczego .... ?

0

Dobra ogarnąłem :D Działa :D Tylko mam jeszcze 1 pytanie ....

0

Chyba zapomniałeś napisać cóż to za pytanie :D

0

Bo zrezygnowałem, myślę że to nie ważne , ale się dopytujesz to ... W zadaniu liczony jest czas na odpowiedzi... W momencie wywoływania 2 raz funkcji(wyjątek), czas jest resetowany i liczony od 0.. Logiczne... Pytanie czy masz pomysł jak zrobić żeby w jakiś sposób sumował może te czasy... Dodam że czas ma być zwracany z funkcji (treść zadania).

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