• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Try catch wykonuje się kilka razy bez powodu

Object Storage Arubacloud
+1 głos
302 wizyt
pytanie zadane 5 maja 2021 w C i C++ przez Mavimix Dyskutant (8,390 p.)

Mam taką funkcję:

int x = NULL, y = NULL;
std::string temp;

void mojaFunckja(std::string alert)
{
	std::cout << alert << std::endl;

	if (NULL == x)
	{
		std::cout << "Podaj x: ";

		try
		{
			getline(std::cin, temp);
			x = std::stoi(temp);

			if (x <= 0)
			{
				x = NULL;
				throw std::logic_error("Wartosc musi byc >0");
			}
		}
		catch (std::invalid_argument) {
			mojaFunckja("Zla wartosc");
		}
		catch (std::logic_error e) {
			mojaFunckja( e.what() );
		}
		catch (std::exception e) {
			mojaFunckja("Blad: " + static_cast<std::string>(e.what()));
		}
		catch (...) {
			mojaFunckja("Nieznany blad");
		}
	}
	else {
		std::cout << "Podaj x: " << x << std::endl;
	}

	std::cout << "Podaj y: ";

	try
	{
		getline(std::cin, temp);
		y = std::stoi(temp);

		if (y <= 0)
		{
			y = NULL;
			throw std::logic_error("Wartosc musi byc >0");
		}
	}
	catch (std::invalid_argument) {
		mojaFunckja("Zla wartosc");
	}
	catch (std::logic_error e) {
		mojaFunckja(std::string(e.what()));
	}
	catch (std::exception e) {
		mojaFunckja("Blad: " + static_cast<std::string>(e.what()));
	}
	catch (...) {
		mojaFunckja("Nieznany blad!");
	}

	std::cout << y<<std::endl;
	std::cout << x<<std::endl;
}

Chcę aby po wpisaniu błędnej wartości x funkcja się uruchomiła ponownie, a gdy błędna jest wartość y program wyświetlił podaną wartość x ("Podaj x: x") a potem znów poprosił o podanie wartości y. Wszystko dobrze działa dopóki nie poda się złej wartości (np. "abcd" zamiast liczby itd.). Po wpisaniu błędnej wartości program jakby wraca do wyjątku tyle razy ile wystąpił błąd w w trakcie wykonywania funkcji i w efekcie albo 2 ostatnie linijki działają kilka razy albo kod "Podaj wartość y: " wykonuje się kilka razy. Nie wiem dlaczego tak jest i jak to naprawić. Z góry dzięki za pomoc.

1 odpowiedź

+3 głosów
odpowiedź 5 maja 2021 przez j23 Mędrzec (194,920 p.)
wybrane 6 maja 2021 przez Mavimix
 
Najlepsza

Nie wiem dlaczego tak jest  (...)

Jest tak dlatego, że wykonujesz funkcję rekurencyjnie.

(...) i jak to naprawić.

Napisać po ludzku funkcję, bez wyjątków i rekurencji. Zwykła pętla wystarczy.

komentarz 5 maja 2021 przez Mavimix Dyskutant (8,390 p.)
edycja 5 maja 2021 przez Mavimix
Skoro pętla wystarczy to w jaki sposób zwalidować dane np. w funkcji stoi?
komentarz 5 maja 2021 przez j23 Mędrzec (194,920 p.)
int readValue(const char* text)
{
    int v;

    while (1) {   
        std::cout << text; 
        std::cin >> v;
        
        if(std::cin.fail()){
            std::cout << "Nieprawidlowy format liczby\n";
            std::cin.clear();
            std::cin.ignore(666, '\n');
            continue;
        }
        
        if(v <= 0) {
            std::cout << "Wartosc musi byc >0\n";
            continue;
        }
        
        break;
    }
    
    return v;
}

int main()
{
    int x = readValue("Podaj x: ");
    int y = readValue("Podaj y: ");
    
    std::cout << x << ", " << y << '\n';
}

 

komentarz 5 maja 2021 przez Mavimix Dyskutant (8,390 p.)
Ok to rozumiem, faktycznie można w ten sposób to zrobić, ale chciałbym zrozumieć i dowiedzieć się dlaczego napisany przeze mnie kod nie działa. Jakiś pomysł?
komentarz 5 maja 2021 przez j23 Mędrzec (194,920 p.)

No to pisałem, że chodzi o rekurencję. Jeśli zrobisz błąd w x, to w obsłudze błędu wywołujesz tę samą funkcję. I jeśli w niej podasz poprawnie x i y, to po wyskoczeniu z funkcji zostaniesz znowu poproszony o podanie wartości y.

void mojaFunckja(std::string alert)
{
    /* ...  */
    
        catch (std::invalid_argument) {
            mojaFunckja("Zla wartosc"); // po wyskoczeniu stąd ...
        }
 
 
    std::cout << "Podaj y: "; //... funkcja jest dalej kontynuowana
 
    /* itd */
}

Wystarczy dać return w catch i problem powinien zniknąć.

komentarz 5 maja 2021 przez Mavimix Dyskutant (8,390 p.)
Czyli dobrze rozumiem, że try..catch po wykonaniu funkcji catch nie "stopuje" funkcji, nie robi break czy coś w tym stylu i po prostu idzie dalej z kodem?
1
komentarz 5 maja 2021 przez Wiciorny Ekspert (269,710 p.)

jeśli nie obsługujesz błędu, nie zwracasz i nie robisz innej akcji to po prostu łapie Ci wyjątek i idzie dalej
 

catch (std::exception e) {
            mojaFunckja("Blad: " + static_cast<std::string>(e.what()));
        }

catch wyłapie execption, ale ty wywołujesz funkcje 
mojaFunckja("Blad: " + static_cast<std::string>(e.what()));
Wiec ona znowu odpala się od początku i leci dalej, stąd duplikacje tak jak tkz napisal rekurencja. 

1
komentarz 6 maja 2021 przez Mavimix Dyskutant (8,390 p.)
Ok dzięki za odp.

Podobne pytania

0 głosów
1 odpowiedź 272 wizyt
pytanie zadane 24 marca 2021 w C# przez Xames Nowicjusz (240 p.)
0 głosów
1 odpowiedź 125 wizyt
pytanie zadane 5 maja 2020 w Java przez danielo665 Obywatel (1,040 p.)
0 głosów
2 odpowiedzi 144 wizyt
pytanie zadane 28 marca 2021 w C i C++ przez Mavimix Dyskutant (8,390 p.)

92,551 zapytań

141,393 odpowiedzi

319,522 komentarzy

61,936 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...