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

Jak zaimplementować try/catch?

Object Storage Arubacloud
+1 głos
985 wizyt
pytanie zadane 27 sierpnia 2017 w Java przez Patryk Moros Początkujący (470 p.)

Hej, mimo prób ogarnięcia tematu nadal nie rozumiem jak implementować wyłapywanie wyjątków/złego inputu użytkownika. Czy mógłby mi ktoś to wytłumaczyć na przykładzie poniższej apki konsolowej do wyciągania pierwiastka?

 

import java.util.Scanner;

public class Application {
	public static void main(String[] args) {
		for (;;) {
			Scanner scanner1 = new Scanner(System.in);
			System.out.print("Throw a number: ");
			double x = scanner1.nextDouble();

			double y = Math.sqrt(x);
			System.out.println("The value is: " + y);
		}
	}
}

Chodzi dokładnie o to, żeby jedynym akceptowalnym inputem była liczba, a jeśli użytkownik wprowadzi coś innego, to wyświetlenie błędu i prośba o input jeszcze raz.

3 odpowiedzi

+1 głos
odpowiedź 27 sierpnia 2017 przez Wildee Gaduła (3,380 p.)
wybrane 27 sierpnia 2017 przez Patryk Moros
 
Najlepsza

Należy sobie najpierw odpowiedzieć, jaki wyjątek dostajemy, kiedy do Scannera wprowadzimy znak inny od liczby. Jest to łatwe do sprawdzenia - włączamy program, wpisujemy błędy znak i sprawdzamy w konsoli :P Okazuje się, że to InputMismatchException. Teraz wystarczy to zaimplementować, a kod wygląda tak: 

import java.util.InputMismatchException;
import java.util.Scanner;

public class Aplikacja {
	public static void main(String[] args) {
		Scanner scanner1 = new Scanner(System.in); // wcześniej ta linia była umieszczona w pętli
		double x;
		double y;
		for (;;) {
			try {
				System.out.print("Throw a number: ");
				x = scanner1.nextDouble();
				y = Math.sqrt(x);
				System.out.println("The value is: " + y);
			} catch (InputMismatchException ex) {
				System.out.println("It's not a number!");
			}
			scanner1.nextLine(); // Jeśli tego nie dodamy, to Scanner cały czas będzie wczytywał nasz błędny
									// znak. Możesz sprawdzić, jak program działa bez tej linii ;) Umieść ją na
									// chwilę w komentarzu

		}
	}
}

 

Dodałem również wywołanie konstruktora Scannera przed pętlę. Nie ma sensu wywoływać go w kółko, to tylko obciąża program (choć w przypadku tak małego programu nie ma to znaczenia, ale ja uważam, że warto kultywować dobre nawyki od początku :P).

1
komentarz 27 sierpnia 2017 przez Patryk Moros Początkujący (470 p.)
A ja się właśnie męczyłem, bo wyjątek wyłapywałem, ale nie dochodziło w ogóle do sysouta z bloku catch. Dzięki wielkie za pomoc. Teraz muszę ogarnąć dlaczego tak a nie inaczej. Jeśli jeszcze mógłbyś mi wytłumaczyć dlaczego na końcu jest scanner1.nextLine(); a nie nextDouble ?
1
komentarz 27 sierpnia 2017 przez Wildee Gaduła (3,380 p.)

Scanner w ten sposób przechodzi do nastepnej linii (i przy okazji zwraca wartość linii, z której przeskoczył, ale nas to w tym momencie nie interesuje). Jeśli nie wywołamy metody nextLine(), to w przypadku, kiedy wprowadzimy coś innego niż double, Scanner będzie w kółko czytał to coś. Dlaczego tak się nie dzieje w przypadku nextDouble()? Ponieważ po udanym wykonaniu nextDouble() Scanner przejdzie niejako za liczbę, którą wprowadziliśmy. Można wyobrazić sobie to na przykładzie kursora, kiedy piszemy tekst. Zrobiłem mały obraz, aby to lepiej objaśnić :) Czerwona kreska, to miejsce Scannera. W razie jakichkolwiek jeszcze wątpliwości śmiało pytaj.

1
komentarz 27 sierpnia 2017 przez Patryk Moros Początkujący (470 p.)
edycja 27 sierpnia 2017 przez Patryk Moros
Wydaje mi się, że już rozumiem :) Było to dla mnie mylące gdyż nextLine() występuję dla wczytywania String w skanerze (np. String a = scanner1.nextLine();), a my tu przecież cały czas o liczbach :).
1
komentarz 27 sierpnia 2017 przez Wildee Gaduła (3,380 p.)
Bo to nie przenosi "nas", a Scanner. W tym wypadku ten, na który wskazuje zmienna scanner1 :) Tu nie chodzi o okno konsoli. Tu chodzi o "okno" Scannera, a jest ono inne niż okno konsoli. Jeśli dalej jest to niezrozumiałe, to pisz, postaram się lepiej wytłumaczyć :P
komentarz 27 sierpnia 2017 przez Patryk Moros Początkujący (470 p.)
Tak, już rozumiem. Olśniło mnie jak zatwierdziłem komentarz i szybko poprawiłem, żeby dalej się nie ośmieszać. Niestety zdążyłeś przeczytać.

Dzięki wielkie za pomoc i cierpliwość :)
1
komentarz 27 sierpnia 2017 przez Wildee Gaduła (3,380 p.)
Kto pyta, nie błądzi. To ja dziękuję! Była to dla mnie czysta przyjemność i możliwość odświeżenia sobie informacji :)
2
komentarz 31 sierpnia 2017 przez Ehlert Ekspert (212,990 p.)

Moim drodzy pętle umieszczamy wewnątrz try-catch, nie odwrotnie.

komentarz 31 sierpnia 2017 przez Wildee Gaduła (3,380 p.)
Ehlert dobrze mówi. Nawet nie zauważyłem, że zrobiłem to w ten sposób :O Dzięki! :)
+1 głos
odpowiedź 27 sierpnia 2017 przez mbabane Szeryf (79,280 p.)

Chociazby tak

for (;;)
{
   try
   {
     Scanner scanner1 = new Scanner(System.in);
     System.out.print("Throw a number: ");
     double x = scanner1.nextDouble();

     double y = Math.sqrt(x);
     System.out.println("The value is: " + y);
   }
   catch(InputMismatchException e)
   {
      System.out.println("Podawaj tylko liczby");
   }
}

A jak chcesz wiecej teorii to wpisz w google Java Wyjatki i bedzie milion materialow.

komentarz 27 sierpnia 2017 przez Patryk Moros Początkujący (470 p.)
edycja 27 sierpnia 2017 przez Patryk Moros
Już próbowałem tego rozwiązania i konsola podawała tylko rodzaj błędu i kod nie wykonywał sysouta.

[edycja]

Przepraszam, oczywiście coś zjadłem i dlatego nie wykonywało. Rozwiązanie działa. :)
0 głosów
odpowiedź 31 sierpnia 2017 przez Patryk Moros Początkujący (470 p.)

Cały czas ćwiczyłem try/catch i napisałem program do ćwiczenia liczenia w pamięci. Wszystko świetnie się spisuje, jak padnie zła odpowiedź to pytanie jest ponawiane, tylko w przypadku wystąpienia wyjątku pytanie nie chce się powtórzyć. Ma ktoś pomysł jak implementować wyjątek w podobnych sytuacjach? Przedstawiam kawałek kodu :)

 

public class Sprawdzanie {

	Procedura procedura = new Procedura();

	Scanner scanner1 = new Scanner(System.in);

	public void dzialania() {

		System.out.println("Wybierz numer operacji: Dodawanie[1], Odejmowanie[2], Mnożenie[3], Dzielenie[4]");
		String wybor = scanner1.nextLine();
		int wynik1;

		Scanner wynik = new Scanner(System.in);

		switch (wybor) {

		// DODAWANIE
		case "1":
			try {
				do {

					System.out.println("Podaj wynik dodawania " + procedura.losowanie1.getL1() + "+"
							+ procedura.losowanie1.getL2());
					wynik1 = wynik.nextInt();
				} while (wynik1 != procedura.dodawanie());
				System.out.println("BRAWO!!! :) :) :) ");
			} catch (InputMismatchException ime) {
				System.out.println("Podaj LICZBĘ");
			}
			break;

		// ODEJMOWANIE
		case "2":
			
			try {

				do {
					System.out.println("Podaj wynik odejmowania " + procedura.losowanie1.getL1() + "-"
							+ procedura.losowanie1.getL2());
					wynik1 = wynik.nextInt();

				} while (wynik1 != procedura.odejmowanie());
				System.out.println("BRAWO!!! :) :) :) ");

			} catch (InputMismatchException ime) {
				System.out.println("Podaj LICZBĘ");
			}
			break;

		// MNOŻENIE
		case "3":
			
			try {

				do {
					System.out.println("Podaj wynik mnożenia " + procedura.losowanie1.getL1() + "*"
							+ procedura.losowanie1.getL2());
					wynik1 = wynik.nextInt();

				} while (wynik1 != procedura.mnożenie());
				System.out.println("BRAWO!!! :) :) :) ");
			} catch (InputMismatchException ime) {
				System.out.println("Podaj LICZBĘ");
			}
			break;

		// DZIELENIE
		case "4":
			
			try {

				do {
					System.out.println("Podaj wynik dzielenia " + procedura.losowanie1.getL1() + ":"
							+ procedura.losowanie1.getL2());
					wynik1 = wynik.nextInt();

				} while (wynik1 != procedura.dzielenie());
				System.out.println("BRAWO!!! :) :) :) ");
			} catch (InputMismatchException ime) {
				System.out.println("Podaj LICZBĘ");
			}
			break;

		default:
			System.out.println("Nieznana komenda");

		}
	}
}

 

komentarz 1 września 2017 przez mbabane Szeryf (79,280 p.)
Chyba dlatego ze try catch jest na zewnatrz petli. W momencie wejscia w catch petla jest przerywana i case sie konczy.

Podobne pytania

0 głosów
1 odpowiedź 515 wizyt
pytanie zadane 9 lipca 2019 w Java przez magicznyukf Początkujący (260 p.)
0 głosów
2 odpowiedzi 463 wizyt
0 głosów
1 odpowiedź 135 wizyt
pytanie zadane 5 maja 2020 w Java przez danielo665 Obywatel (1,040 p.)

92,696 zapytań

141,607 odpowiedzi

320,114 komentarzy

62,055 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

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!

...