Odczyt z pliku do tablicy

0

Witam,
męczę się już solidne parę godzin nad prostym projektem z Javy, jestem początkujący i błędy chyba mogą się zdarzać. Chcę zrobić odczyt danych z pliku i przyporządkować je odpowiednim komórkom tablicy powiązanych z klasą Pracownik. Klasa pracownik składa się ze stringa nazwisko, integera pensja i booleana urlop. Chcę to zrobić za pomocą Scannera i nie wiem czy to odpowiednie podejście. Nie wiem czy zły jest mój odpowiednik EOF w C czy błąd leży gdzieś indziej. Ułatwiając sobie pracę zapisuję kolejne dane w nowych liniach pliku (zapis działa bez problemu). Odczyt dla jednego pracownika bez tego while działał dobrze i dobrze przypisywał więc gdzieś tam dopatruję się błędu. Kompilator wypluwa:

Exception in thread "main" java.lang.NullPointerException.

Fragment mojego kodu z funkcją odczytu.

static void odczytPlik() {
		String nazw;
		int pen;
		boolean url;
		int i=0;
		
		File plik = new File("odczyt.txt");
		
		try {
			odczyt = new Scanner(plik);
		} catch (FileNotFoundException e) {
			System.out.println("Błąd odczytu pliku!");
		}
		
		while(odczyt.hasNextLine()){
			nazw = odczyt.nextLine();
			pen = odczyt.nextInt();
			url = odczyt.hasNext();
			
			praca[i].nazwisko = nazw;
			praca[i].pensja = pen;
			praca[i].urlop = url;
			
			i++;
		}
		
		liczba=i;
	}
1

Tutaj prawdopodobnie jest błąd:

url = odczyt.hasNext();

Daj

odczyt.nextBoolean();
0

O, na ten błąd nie zwróciłem uwagi, dzięki :)
Jednak cały czas wypluwa ten sam error. Eclipse wskazuje na tą linię kodu

praca[i].nazwisko = nazw;
1

Błąd jest wcześniej. W wierszu

pen = odczyt.nextInt();

podczas odczytywania ostatniego wiersza, jesteś wtedy poza plikiem. Zrób to tak:

                while(odczyt.hasNextLine()){
                        String line = odczyt.nextLine();
                        Scanner sc = new Scanner(line);
                        nazwa = sc.next();
                        pen = sc.nextInt();
                        url = sc.nextBoolean();
 
                        praca[i].nazwisko = nazw;
                        praca[i].pensja = pen;
                        praca[i].urlop = url;
 
                        i++;
                }

Btw, czy http://4programmers.net/Forum/Newbie/151743-metoda_wczytujaca_dane_z_pliku_do_listy, to kolega z grupy.

0

a sprobuj przy czytaniu nazw dac next(); zamiast nextLine(); :P

0

Mój plik 'odczyt.txt' wygląda tak:

Kowalski
3500 
false
Nowak
4000 
false

Po przerobieniu kodu na Twój sposób eclipse podaje takie błędy:

Exception in thread "main" java.util.NoSuchElementException
	at java.util.Scanner.throwFor(Unknown Source)
	at java.util.Scanner.next(Unknown Source)
	at java.util.Scanner.nextInt(Unknown Source)
	at java.util.Scanner.nextInt(Unknown Source)
	at Obsluga.odczytPlik(Obsluga.java:97)

Linia 97 to:

pen = sc.nextInt();

Z tego co rozumiem to nie do końca łapie powiązanie Scannera sc z plikiem .txt?
Nie do końca też rozumiem czemu te instrukcje wychodzą poza plik. Myślałem, że działają mniej więcej w ten sposób:

while (sprawdza czy istnieje w pliku następna linia) {
 trzy kolejne instrukcje czytają trzy kolejne linie w pliku
 wpisują wartości tych linijek do tablicy
 zwiększenie i
}

więc kiedy nie ma następnej linii to ten while powinien się zakończyć. Gdzie jest błąd w moim rozumowaniu? :)

ah, no i tamten ktoś to raczej nie kolega z grupy, podobieństwo zadania każe myśleć, że może ktoś z roku.

0

A pokaż jak i gdzie inicjujesz tablice praca.

1
  1. Wypadało strukturę pliku podać od razu.
  2. Błędnie zakładasz, że metoda nextBoolean() czyta wszystko, łącznie z końcem linii. A to nieprawda.
                while(odczyt.hasNextLine()){
                        nazw = odczyt.nextLine();
                        pen = odczyt.nextInt();
                        url = odczyt.hasNextBoolean();
                        odczyt.nextLine(); //odczytanie końca wiersza
 
                        praca[i].nazwisko = nazw;
                        praca[i].pensja = pen;
                        praca[i].urlop = url;
 
                        i++;
                }
0

Klasa Obsługa

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

public class Obsluga {
	
	static int liczba=0;
	
	static Pracownik[] praca = new Pracownik[10];
	
	private static Scanner czyt;
	private static Scanner odczyt;
	private static PrintWriter zapis;
	
	static void wyswietlMenu(){
	(...)
	}
	
	static void wyswietlPracownika(){
	(...)
	}
	
	static void dodajPracownika(){
	(...)
	}

	
	static void podwyzkaPracownik(){
	(...)
	}
	
	static void urlopPracownik(){
	(...)
	}
	
	static void odczytPlik() throws FileNotFoundException {
		String nazw;
		int pen;
		boolean url;
		int i=0;
		
		File plik = new File("raport.txt");
		odczyt = new Scanner(plik);
		
		while(odczyt.hasNextLine()){
			nazw = odczyt.nextLine();
			pen = odczyt.nextInt();
			url = odczyt.hasNextBoolean();
			odczyt.nextLine(); //odczytanie końca wiersza

			praca[i].nazwisko = nazw;
			praca[i].pensja = pen;
			praca[i].urlop = url;

			i++;
		}	
		
		liczba=i;
	}
	
	static void zapisPlik() throws FileNotFoundException{
		int i;
		
		zapis = new PrintWriter("raport.txt");
		for(i=0;i<liczba;i++){
			zapis.println("" + praca[i].nazwisko);
			zapis.println("" + praca[i].pensja); 
			zapis.println("" + praca[i].urlop);
		}
		zapis.close();
	}
	
	public static void main(String[] args) throws IOException {
	
		boolean x=true;
		Scanner wybor;

		odczytPlik();
		
		while(x){
			wyswietlMenu();
			System.out.print("Twoj wybor: ");
			wybor = new Scanner(System.in);
			char c = wybor.next().charAt(0);
			
			switch(c){
			case 'a': wyswietlPracownika(); break;
			case 'b': dodajPracownika(); break;
			case 'c': podwyzkaPracownik(); break;
			case 'd': urlopPracownik(); break;
			case 'e' : zapisPlik(); break;
			case 'x': x=false; break;
			default: break;
			}
		
		}
		
	}

}

Błędy dotyczą:

 
Exception in thread "main" java.lang.NullPointerException
	at Obsluga.odczytPlik(Obsluga.java:93) // praca[i].nazwisko = nazw;
	at Obsluga.main(Obsluga.java:123) // odczytPlik();

Do tego klasa Pracownik:

public class Pracownik {

	public Pracownik(String string, int i, boolean b) {
		// TODO Auto-generated constructor stub
		nazwisko=string;
		pensja=i;
		urlop=b;
	}
	
	String nazwisko;
	int pensja;
	boolean urlop;	
	
}

Nie mam pomysłu co więcej mogę poprawić w odczytywaniu danych z pliku tak więc może błąd leży gdzieś indziej. Nie widzę spoilerów więc nie wiem jak zmniejszyć kod, żeby nie przeszkadzał.

1

Nie widzę nigdzie inicjacji elementów tablicy praca.

for(int i=0;i<praca.length;i++)
{
    praca[i] = new Pracownik();
}
1
         while(odczyt.hasNextLine()){
                 nazw = odczyt.next();
                 pen = odczyt.nextInt();
                 url = odczyt.nextBoolean();
                 praca[i] = new Pracownik();
                 praca[i].nazwisko = nazw;
                 praca[i].pensja = pen;
                 praca[i].urlop = url;

                 i++;
         }  
0

To rozumiem, że ta część nie spełnia takiej roli?
static Pracownik[] praca = new Pracownik[10];

Wstawiając tego while'a trzeba utworzyć nowy constructor?

0

Tworzysz w ten sposób 10 elementową pustą tablice typu Pracownik.
Kiedy robisz int[] liczby = new int[10]; to czy tablica sama wypełnia?

0

olek1 - dziękuję bardzo, Twój post wespół z postami bogdans'a otworzył mi oczy i zrozumiałem o co w tym wszystkim chodzi. Właśnie wpadłem na to, że przecież tworząc pracownika robię to w podobny sposób
praca[i] = new Pracownik(nazw, pen, url);

Jeszcze raz dziękuję za całą Waszą pomoc :)

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