» »

[Java] Problem s Scanner-jem

[Java] Problem s Scanner-jem

Zlatan ::

Potrebujem pomoč glede uporabe razreda Scanner. Delam program, katerega bi v konzoli zagnal in bi se mi pojavil meni. Z vnosom izbire menija (npr. številke 1-4) bi se izvedla določena statična metoda. Gre za nekakšno evidenco gorskih vzponov. Ena od teh izbir je dodajanje vzpona v zbirko, tu pa se pojavi problem. Z vnosom (izborom) številke 2 v mojem primeru, se izvede metoda dodajVzpon(), ki ima svoj Scanner za vnos imena vrha ter datuma. Vnos podatkov se normalno izvede, po vnosu pa bi rad, da se spet izpiše glavni meni. Tu pa nastane problem: ko se glavni meni izpiše, mi program javi napako oz. izjemo java.util.NoSuchElementException zaradi ponovnega skeniranja izbire v glavnem meniju. Izgleda mi, kot da Scanner ne počaka na vnos preko tipkovnice, ne vem pa, zakaj je temu tako oziroma kako bi to popravil. Je mogoče treba vhodni tok "izplakniti"?

Pa še koda:

import java.io.*;
import java.util.*;


public class Glavni {

	public static void main(String[] args) throws FileNotFoundException {
		
		System.out.println("EVIDENCA GORSKIH VZPONOV");
		
		while(true){
			System.out.println();
			System.out.println("Izberi eno izmed možnosti:");
			System.out.println("1 - Izpis osvojenih vrhov");
			System.out.println("2 - Dodaj vzpon");
			System.out.println("3 - Shrani spremembe");
			System.out.println("4 - Zapri program");
				
			Scanner sc = new Scanner(System.in);
			int izbira = sc.nextInt();

			System.out.println("Izbira: "+izbira);
			
			switch(izbira){
				case 1:
					System.out.println("1 izbrana... izpis vzponov");
					//izpisVzponov();
					break;
				case 2:
					System.out.println("2 izbrana... dodajanje opravljenega vzpona");
					dodajVzpon();
					break;
				case 3:
					System.out.println("3 izbrana... shranjevanje sprememb");
					// shraniDatoteko(String ime);
					break;
				case 4:
					System.out.println("4 izbrana... izhod iz programa");
					System.exit(0);
				default:
					System.out.println("Neveljavna izbira!");
					break;
				}
				
			
		}

	}
	
	/*public static void izpisVzponov() throws FileNotFoundException{
		// to-do
	}*/
	
	public static void dodajVzpon(){
		
		System.out.println("Vnesi leto: ");
		Scanner scV = new Scanner(System.in);
		int leto = scV.nextInt();
		System.out.println("Vnesi mesec (1-12): ");
		int mesec = scV.nextInt();
		System.out.println("Vnesi dan v mesecu (1-31): ");
		int dan = scV.nextInt();
		scV.close();
		Datum datum = new Datum(leto,mesec,dan);
		datum.izpisiDatum();
	}

	/*public static void shraniDatoteko(){
		// to-do
	}*/
	
}

_Dormage_ ::

Si omejen na Scanner class?
Jaz mam raje
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            String input = reader.readLine();

Zlatan ::

_Dormage_ je izjavil:

Si omejen na Scanner class?
Jaz mam raje

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String input = reader.readLine();


Načeloma nisem omejen na Scanner, mi je pa tudi Pri BufferedReader-ju vrglo ven I/O izjemo, tako da mora biti neka fora, da je Scanner oz. BufferedReader "prehiter", da bi počakal na vhod.

Če kdo natančneje ve, kako Scanner (ali pa konec koncev tudi BufferedReader) deluje, ga lepo prosim za razlago.

Spura ::

To se zato dogaja ker se spet copy pastea koda, katere dejanskega pomena se ne pozna. Namesto, da bi uporabljal en scanner jih ti naredis vec. In po vnosu vzpona zapres scanner, kar zapre stream, kar pomeni da naslednji scanner naleti na zaprt stream.

Zlatan ::

Ok, to je res, da bi lahko uporabljal le en Scanner. Ampak še vedno mi ni jasno, zakaj bi bil stream zaprt, če pa po izpisu menija ponovno ustvarim primerek Scannerja...

_Dormage_ ::

Tukaj maš razlago zakaj ni dobro uporabljat več instanc Scanner classa.

Spura ::

Zlatan je izjavil:

Ok, to je res, da bi lahko uporabljal le en Scanner. Ampak še vedno mi ni jasno, zakaj bi bil stream zaprt, če pa po izpisu menija ponovno ustvarim primerek Scannerja...

Si pogledal kako streami delujejo? Ko ga zapres je konec (z izjemami kot so ByteArray(Input/Output)Stream). Ti zapres scanner kar zapre System.in stream in naredis nov scanner in mu podas zaprt stream.

Zlatan ::

Aha, sem pa predvideval, da se z inicializacijo
Scanner sc = new Scanner(System.in);
posledično tudi stream odpre. Torej uporabiti moram en Scanner vseskozi, pri klicu metode za vnos vzpona pa ta Scanner dam kot argument, zaprem ga pa šele ob izhodu iz programa, kajne?

Hvala za razlago.

Spura ::

Zlatan je izjavil:

Aha, sem pa predvideval, da se z inicializacijo
Scanner sc = new Scanner(System.in);
posledično tudi stream odpre.

Ali ima stream open() funkcijo?

Zlatan je izjavil:


Torej uporabiti moram en Scanner vseskozi, pri klicu metode za vnos vzpona pa ta Scanner dam kot argument, zaprem ga pa šele ob izhodu iz programa, kajne?

Hvala za razlago.
Ni nujno da je samo en scanner, samo zapret ga ne smes. Je pa bolj smiselno imeti samo enega. Zapret ga ni treba, ker scanner je tokenizator, ki razen streama nima resourcov, stream System.in se bo pa avtomatsko zaprl ob izhodu.

Zlatan ::

Še eno sorodno vprašanje. Zamislu sm si naredit neko simpl evidenco filmov. Imam isto meni kot zgoraj, pri dodajanju novega filma v evidenco pa se zatakne.

Del kode, kjer berem podatke iz vhoda:
System.out.println("VNOS NOVEGA FILMA:");
			System.out.println("Naslov filma: ");
			String naslov=sc.nextLine();
			System.out.println("Leto: ");
			String leto=sc.nextLine();
			System.out.println("Zvrst: ");
			String zvrst=sc.nextLine();
			System.out.println("Trajanje: ");
			String trajanje=sc.nextLine();
			System.out.println("Pogledan (DA/NE): ");
			String pogledan=sc.nextLine();
			Film nov=new Film(naslov,leto,zvrst,trajanje,pogledan);


Ko pokličem funkcijo za vpis novega filma, v kateri je tale koda, mi izpiše

Naslov filma:
         Leto:


in potem čaka na input, namesto da bi izpisal samo

Naslov filma:


Kaj ga je tukaj zmešalo?


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Java začetnik - pravilno število

Oddelek: Programiranje
7940 (663) roko granata
»

Java - dva problema

Oddelek: Programiranje
141640 (1248) nightrage
»

Java problem

Oddelek: Programiranje
201509 (1207) infiniteLoop
»

[Java] Kako filtrirati, katera števila lahko vpišeš?

Oddelek: Programiranje
181998 (1700) fiction
»

[JAVA] zaustavitev niti (threadov)

Oddelek: Programiranje
223042 (3042) morbo

Več podobnih tem