Zapis/odczt tablicy liczb do pliku tekstowego

0

Witam. Mam problem z rozwiązaniem pewnego zadania, a mianowicie chodzi o wygenerowanie dwuwymiarowej tablicy liczb, zapis tablicy do pliku tekstowego oraz odczyt macierzy z pliku do tablicy w pamięci i jej wyświetlenie. Z zapisem i odczytem SAMEJ tablicy nie mam problemu, jednak plik tekstowy powinien wyglądać według schematu:

  • wiersz 1: tekst "Macierz",
  • wiersz 2: liczba wierszy,
  • wiersz 3: liczba kolumn,
  • dalsze wiersze: kolejne wiersze tablicy.
    Nie wiem za bardzo jak poradzić sobie z odczytaniem macierzy, pomijając 3 pierwsze wiersze.
    Tutaj mój kod:
import java.util.*;
import java.io.File;
import java.io.PrintWriter;
import java.io.FileNotFoundException;
public class Pliki 
{
	private int tab[][];
	private int w,k;
	
	public Pliki()
	{
		tab = new int[0][0];
	}
	
	public void setRozmiar(int w, int k)
	{
		this.w=w;
		this.k=k;
		tab=new int[w][k];
	}
	
	public void Wypelnij()
	{
	  Random rand = new Random();
	   
	  for(int i=0; i<w; i++)
		  for(int j=0;j<k;j++)		    	
			  tab[i][j]=rand.nextInt(9)+1;
	}
	
	public void Zapisz()throws FileNotFoundException
	{
		PrintWriter zapis = new PrintWriter("tablica.txt");
	    zapis.println("Macierz");
	    zapis.println(w);
	    zapis.println(k);
	    for(int i=0; i<w; i++)
		  {
		   for(int j=0; j<k; j++) 		
			   zapis.print(tab[i][j]+"\t");
		   	   zapis.println();
		  }
	      zapis.close();
	}
	
	public void Odczytaj()throws FileNotFoundException
	{
		int temp[][]=new int[w][k];
		try
		{
		Scanner odczyt = new Scanner(new File("tablica.txt"));
		  for(int i=0; i<w; i++)
		    {
		    	for(int j=0; j<k; j++)
		    	{
		    		temp[i][j]=odczyt.nextInt();
		    	}
		    }
		  odczyt.close();
		}
		catch (Exception e) 
		{
			System.err.println("błąd odczytu danych");
			System.exit(0);
		}
		  for(int i=0; i<w; i++)
		    {
		    	for(int j=0; j<k; j++)	    
		    		System.out.print("["+temp[i][j]+"] ");
		    		System.out.println();
		    }
	}
	
	public static void menu()
	{
		System.out.println("MENU:\n1.Stwórz nową tablicę");
		System.out.println("2.Zapis tablicy do pliku");
		System.out.println("3.Odczyt tablicy z pliku");
		System.out.println("4.Wyjście");
	}
	
	public static void main(String[] args)throws FileNotFoundException
	{
		Scanner input = new Scanner(System.in);
		
		Pliki tablica=new Pliki();

		menu();
		int menu=' ';
		while(menu!=4)
		{
		menu=input.nextInt();
			switch(menu)
			{
			case 1:
				System.out.println("Podaj rozmiar tablicy");
				tablica.setRozmiar(input.nextInt(),input.nextInt());
				tablica.Wypelnij();
				menu();
			break;
			
			case 2:
				tablica.Zapisz();
				menu();
			break;
			
			case 3:
				tablica.Odczytaj();
				menu();
			break;
			
			case 4:
				tablica.Zapisz();
				System.exit(0);
			default:
				System.out.println("Nieprawidłowy wybór");
			break;	
			}
		}

	}

}

Czy problem ten można rozwiązać przy pomocy klasy Scanner(tej własnie klasy użyłem do odczytu danych z pliku) czy powinienem raczej skorzystać z czegoś innego?
Bardzo prosiłbym o jakieś wskazówki.

EDIT:
Dobra, jakoś sobie poradziłem. Przerobiłem metodę Odczytaj() na coś takiego:

public void Odczytaj()throws FileNotFoundException
	{
		Scanner odczyt = new Scanner(new File("tablica.txt"));
		System.out.println(odczyt.nextLine());
		int wiersze=odczyt.nextInt();
		int kolumny=odczyt.nextInt();
		int temp[][]=new int[wiersze][kolumny];
		
		try
		{
		
		  for(int i=0; i<wiersze; i++)
		    {
		    	for(int j=0; j<kolumny; j++)
		    	{
		    		temp[i][j]=odczyt.nextInt();
		    	}
		    }
		  odczyt.close();
		}
		catch (Exception e) 
		{
			System.err.println("błąd odczytu danych");
			System.exit(0);
		}
		  for(int i=0; i<wiersze; i++)
		    {
		    	for(int j=0; j<kolumny; j++)	    
		    		System.out.print("["+temp[i][j]+"] ");
		    		System.out.println();
		    }
	}

Jednak zdaję sobie sprawę, że jest to złe rozwiązanie. W tym przypadku wykorzystałem dane w kolejnych wierszach, ale co jeśli rzeczywiście musiałbym "ominąć" część danych?

0

Wtedy je po prostu omijasz? :) Np. poprzez rozpoczęcie uzupełniania tabeli od wiersza, który zawiera \t, czy inny biały znak przestankowy.

0

Dobra już ogarnąłem :D Wystarczy pobawić się z instrukcjami warunkowymi i wszystko da sie zrobić. Teraz mam kolejny, dość trywialny wydaje się problem, z którym nie mogę sobie poradzić... Do tej pory cały czas operowałem na intach i wszystko działało prawidłowo. Jednak nie doczytałem, że w zadaniu jest mowa o liczbach rzeczywistych, i za nic nie mogę wczytać tych liczb z pliku.

public void Odczytaj()throws FileNotFoundException
	{
		Scanner odczyt = new Scanner(new File("tablica.txt"));
		System.out.println(odczyt.nextLine());
		int wiersze=odczyt.nextInt();
		int kolumny=odczyt.nextInt();
		double temp[][]=new double[wiersze][kolumny];
		try
		{
		  for(int i=0; i<wiersze; i++)
		    {
		    	for(int j=0; j<kolumny; j++)
		    	{
		    		temp[i][j]=odczyt.nextDouble(); //tutaj wywala mi InputMismatchException
		    	}
		    }
		  odczyt.close();
		}
		catch (Exception e) 
		{
			System.err.println("błąd odczytu danych");
			System.exit(0);
		}
		  for(int i=0; i<wiersze; i++)
		    {
		    	for(int j=0; j<kolumny; j++)	    
		    		System.out.print("["+temp[i][j]+"] ");
		    		System.out.println();
		    }
	}

Czy ma to związek z tym, że w pliku txt. liczby zapisywane są po kropce(np. 6.34) i gdy chcę je potem wczytać ta kropka właśnie powoduje błąd?

0

Tak, Scanner domyślnie "się lokalizuje". Są dwa rozwiązania:

for(int j=0; j<kolumny; j++)
{
      temp[i][j] = Double.parseDouble(odczyt.next());
}

i bardziej elegancko:

Scanner odczyt = new Scanner(new File("tablica.txt"));
odczyt.useLocale(new Locale("US"));
1

trzymaj się konwencji nazewniczych - pisz wszystkie nazwy metod z małej i dalej notacją węgierską. setRozmiar normalnie napisałeś a dalsze metody z dużej zaczynasz :P - pedegie

Proponuję nie mylić notacji węgierskiej ze z camelCasem ;)

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