Lettura da file

di il
21 risposte

Lettura da file

Buonasera
torno a scrivervi, troppo presto lo ammetto, per chiedervi ancora una volta consiglio e aiuto
ormai sapete che sono più o meno alle prime armi e che mi piace "giocare" un po' con la fantasia e le possibilità che java offre
allora cerco di esporre chiaramente i fatti
per motivi non definiti ho creato un file di testo, Automobili.txt e ci ho messo dentro 71 marche di auto, marca, a capo, marca, a capo e via dicendo
ora vorrei leggere quel file e inserire ogni suo valore dentro un array
quindi ho fatto il seguente codice
classe (con scanner):

import java.util.Random;
import java.util.Scanner;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class Automobili
{
	String marche[] = new String[70];
	private String marca;
		
		//assegnazione stringhe all'array marche
		private void vettoreMarche()
		{
			try
			{
				Scanner reader = new Scanner(new FileReader("Automobili.txt")); 
				while (reader.hasNextLine() != true) //fino a quando non ritorna false (riga vuota) allora mi assegni un valore al vettore
				{
					int i = 0;
					marche[i] = reader.nextLine(); //riempio il mio vettore leggendo da file
					i++;
					//return marche[i];
				}
				reader.close();
			}
			catch (FileNotFoundException e)
			{
				System.out.println("io error");
				e.printStackTrace();
			}
		}
		
		//con questo metodo creo un'auto di marca random
		private String setMarcaRandom()
		{
			int tmp = rng.nextInt(71);
			if (tmp == 0) tmp = rng.nextInt(71);
			marca = marche[tmp];
			return marca;
		}
		
		//metodo costruttore
		public Automobili()
		{
			stato = setStatoRandom();
		
			if (stato.equals("false")) //attributi solo per le auto usate
			{
				km = 0.0;
				annoImmatricolazione = 0;
				scadenzaBollo = 0;
				//targa = setTarga();
			}
			else //l'auto è nuova, non servon questi valori
			{
				targa = null;
				km = 0.0;
				annoImmatricolazione = 0;
				scadenzaBollo = 0;
			}
		
			marca = setMarcaRandom();
		}
		
		public String getStato()
		{
			return stato;
		}
	
		public String getMarca()
		{
			return marca;
		}
}
classe (con bufferedreader):

import java.util.Random;
import java.util.Scanner;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class Automobili
{
	String marche[] = new String[70];
	private String marca;
		
		//assegnazione stringhe all'array marche
		private void vettoreMarche()
		{
			try
			{
				BufferedReader reader = new BufferedReader(new FileReader("Automobili.txt")); 
				while (reader.readLine() != null) //fino a quando non ritorna null (riga vuota) allora mi assegni un valore al vettore
				{
					int i = 0;
					marche[i] = reader.readLine(); //riempio il mio vettore leggendo da file
					i++;
					//return marche[i];
				}
				reader.close();
			}
			catch (FileNotFoundException e)
			{
				System.out.println("io error");
				e.printStackTrace();
			}
			catch (IOException e1)
			{
				System.out.println("io error");
				e1.printStackTrace();
			}
		}
		
		//con questo metodo creo un'auto di marca random
		private String setMarcaRandom()
		{
			int tmp = rng.nextInt(71);
			if (tmp == 0) tmp = rng.nextInt(71);
			marca = marche[tmp];
			return marca;
		}
		
		//metodo costruttore
		public Automobili()
		{
			stato = setStatoRandom();
		
			if (stato.equals("false")) //attributi solo per le auto usate
			{
				km = 0.0;
				annoImmatricolazione = 0;
				scadenzaBollo = 0;
				//targa = setTarga();
			}
			else //l'auto è nuova, non servon questi valori
			{
				targa = null;
				km = 0.0;
				annoImmatricolazione = 0;
				scadenzaBollo = 0;
			}
		
			marca = setMarcaRandom();
		}
		
		public String getStato()
		{
			return stato;
		}
	
		public String getMarca()
		{
			return marca;
		}
}

mentre il mio main, semplice semplice, è questo
1) ho provato a fare una lettura del file per vedere se effettivamente lo vede, e lo vede, non mi rimanda errori. questo l'ho provato sia con lo scanner, sotto, sia con il bufferedreader. risultato sempre lo stesso. riga vuota

import java.util.Random;
import java.util.Scanner;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class Salone
{
	public static void main(String[] args)
	{
		//Automobili auto = new Automobili();
		//System.out.println("auto 1, stato: " + auto.getStato() + ", marca: " + auto.getMarca());
		String marche[] = new String[70]; 
		
		try
		{
			Scanner reader = new Scanner(new FileReader("Automobili.txt")); //BufferedReader
			while (reader.hasNextLine() != true) //fino a quando non ritorna null (riga vuota) allora mi assegni un valore al vettore
			{
				int i = 0;
				marche[i] = reader.nextLine(); //riempio il mio vettore leggendo da file
				System.out.println("marca: " + marche[i]);
				i++;
				//return marche[i];
			}
			reader.close();
		}
		catch (FileNotFoundException e)
		{
			System.out.println("io error");
			e.printStackTrace();
		}
		
	}
}
mentre il main che usa la classe automobili e il suo oggetto. questo mi restituisce, su auto 1 usata o nuova, su marca mi da null

public class Salone
{
	public static void main(String[] args)
	{
		Automobili auto = new Automobili();
		System.out.println("auto 1, stato: " + auto.getStato() + ", marca: " + auto.getMarca());
		
		
	}
}
bene spero di essermi spiegato bene e che il codice sia sufficientemente chiaro
la mia domanda è: perché non mi funziona?
allego anche il file automobili.txt, a cui per provare ho aggiunto un ; dopo il nome della marca, ma non è cambiato nulla
sono sicuro che sarà una cosa stupida a cui alle 2 di notte quasi, non ci ho pensato ma ne approfitto per chiedere comunque, magari, come per le mappe, imparerò qualcosa di nuovo dalle vostre spiegazioni

21 Risposte

  • Re: Lettura da file

    Ahahaha ok si vede che è l'ora^^' nello scanner il valore nel while non deve essere false mentre il metodo non mi funziona perché il valore non esce dal while mmh ok... probabilmente ho fatto altri errori ma questi intanto li ho capiti, ora bisogna risolverli uhm
  • Re: Lettura da file

    Ok domanda che può sembrare molto stupida:
    perché con il for riesco a far uscire i dati dal cilo mentre con il while no?
    non credo centri la dichiarazione di i dentro al while no? alla fine è la stessa cosa del for

    edit:
    bhe effettivamente se dichiaro la i fuori dal while allora funziona...
    ma dichiararla nello statment del for oppure dentro al while, non è la stessa cosa?
    scusate, so che questa è ignoranza pura

    edit2:
    son riuscito a far funzionare anche il bufferedreader, anche se non capisco perché, mi prende solo 35 voci su 71...

    edit3:
    dopo questa vado a dormire giuro.
    perché il metodo
    
    	public String setMarcaRandom()
    	{
    		int tmp = rng.nextInt(71);
    		marca = marche[tmp];
    		return marca;
    	}
    
    della classe automobili (vedere primo post, c'è lo script completo) mi ritorna null? non ci arrivo proprio. in teoria gli sto dicendo:
    1) mi crei una variabile "temporanea" a cui assegni un random da 0 a 71
    2) mi assegni alla variabile marca, dichiarata all'inizio della classe, il valore nella posizione data da tmp del vettore marche
    3) mi ritorni la variabile modificata
    giusto no? o mi son perso qualche passaggio base?
  • Re: Lettura da file

    Allora andiamo con ordine: il primo codice che hai postato non è completo (mancano alcune variabili che usi in seguito) ma già si vedono alcune cose parecchio dubbie.
    Perché la tua classe automobili ha un campo marca (con metodo get associato) e un costruttore in cui inizializzi km, annoImmatricolazione, targa etc., valori che tra l'altro non si vede come usi in seguito?

    Questo mi sembra un terribile macello, in cui mischi informazioni che dovrebbe contenere una classe base (che dovresti chiamare Automobile, e dovrebbe mantenere informazioni relative alla singola automobile, come marca, km, annoImmatricolazione e tutto il resto), con quella che può benissimo essere una classe contenitore/di test come Automobili.

    Può andare bene che Automobili abbia un vettore di marche, creato come vuoi (quindi anche letto dal file, ma ne parliamo dopo), ma quel costruttore di Automobili così come è scritto non ha alcun senso.

    A me sembra che qui serva un bel ripasso delle basi o, se ho capito male io quello che stai cercando di fare (anche perché il codice non è completo), cerca di spiegarti meglio (ma confermo che mi sembra tutto molto dubbio, e una riga come if (stato.equals("false")) è proprio una bestemmia).

    Per quanto riguarda la lettura con Scanner, mi pare che tu abbia capito perché era sbagliato, tieni comunque presente che:
    
    while (reader.hasNextLine() == true)
    
    Andrebbe scritto come:
    
    while (reader.hasNextLine ()) // while (!reader.hasNextLine ()) se vuoi fare la negazione, che in questo caso non ha senso.
    
    Perché un valore boolean è già sufficiente per il test, non serve farne l'uguaglianza o meno con un altro boolean (in pratica staresti scrivendo if (true == true), o simili, quando ti basta if (true)).

    KuroKami69 ha scritto:


    Ok domanda che può sembrare molto stupida:
    perché con il for riesco a far uscire i dati dal cilo mentre con il while no?
    non credo centri la dichiarazione di i dentro al while no? alla fine è la stessa cosa del for

    edit:
    bhe effettivamente se dichiaro la i fuori dal while allora funziona...
    ma dichiararla nello statment del for oppure dentro al while, non è la stessa cosa?
    Se ti riferisci a questa parte di codice (ho solo corretto la condizione del while):
    
    while (reader.hasNextLine())
    {
       int i = 0;
       marche[i] = reader.nextLine(); //riempio il mio vettore leggendo da file
       i++;
       //return marche[i];
    }
    
    La variabile i viene inizializzata a 0 ad ogni iterazione, quindi stai sempre sovrascrivendo la stringa in marche [0].
    Quindi non è che con il while non si riesca a "far uscire i dati" dal ciclo.

    Se il for l'hai invece scritto in questo modo:
    
    for (int i = 0; reader.hasNextLine (); i ++)
    
    Questo vuol dire che i viene inizializzata a 0 subito prima di iniziare la prima iterazione, ma poi ad ogni iterazione viene incrementata, non ritorna a 0 ogni volta, quindi è ben diverso "dichiarare i nello statement del for oppure dentro al while", il for che ho scritto coincide appunto con il dichiarare i fuori dal while, e incrementarla ad ogni iterazione.

    KuroKami69 ha scritto:


    edit2:
    son riuscito a far funzionare anche il bufferedreader, anche se non capisco perché, mi prende solo 35 voci su 71...
    Il codice che stai usando:
    
    while (reader.readLine() != null)
    {
       int i = 0;
       marche[i] = reader.readLine(); //riempio il mio vettore leggendo da file
       i++;
       //return marche[i];
    }
    

    E' sbagliato, perché ad ogni iterazione leggi due righe (con reader.readLine ()), quindi ne butti via una delle due (quella che usi nella condizione del while).
    Quella riga invece va assegnata ad una variabile, altrimenti te la perdi. Il modo consueto per fare questo è il seguente:
    
    String line; // Dichiaro una variabile a cui verrà assegnata in loop ogni riga del file.
    while ((line = reader.readLine ()) != null) { // assegno a line il valore di reader.readLine (), e controllo che non sia uguale a null
    	// uso la variabile line, stavolta senza perdere nessuna riga.
    	// es. marche [i] = line; i ++;
    }
    

    KuroKami69 ha scritto:


    edit3:
    perché il metodo:
    
    public String setMarcaRandom()
    {
    	int tmp = rng.nextInt(71);
    	marca = marche[tmp];
    	return marca;
    }
    

    della classe automobili (vedere primo post, c'è lo script completo) mi ritorna null? non ci arrivo proprio. in teoria gli sto dicendo:
    1) mi crei una variabile "temporanea" a cui assegni un random da 0 a 71
    2) mi assegni alla variabile marca, dichiarata all'inizio della classe, il valore nella posizione data da tmp del vettore marche
    3) mi ritorni la variabile modificata
    giusto no? o mi son perso qualche passaggio base?
    Quello che hai scritto è tecnicamente giusto (a parte il fatto che il numero random va da 0 a 70), bisogna vedere cosa contiene marche all'indice casuale che hai estratto, se la lettura da file non è corretta è possibile (anzi molto probabile) che in molti indici del vettore ci sia ancora il valore null.
  • Re: Lettura da file

    Ciao e grazie mille per la risposta.
    cercherò di rispondere con ordine e di chiarire meglio

    Ansharja ha scritto:


    Allora andiamo con ordine: il primo codice che hai postato non è completo (mancano alcune variabili che usi in seguito) ma già si vedono alcune cose parecchio dubbie.
    Perché la tua classe automobili ha un campo marca (con metodo get associato) e un costruttore in cui inizializzi km, annoImmatricolazione, targa etc., valori che tra l'altro non si vede come usi in seguito?

    Questo mi sembra un terribile macello, in cui mischi informazioni che dovrebbe contenere una classe base (che dovresti chiamare Automobile, e dovrebbe mantenere informazioni relative alla singola automobile, come marca, km, annoImmatricolazione e tutto il resto), con quella che può benissimo essere una classe contenitore/di test come Automobili.

    Può andare bene che Automobili abbia un vettore di marche, creato come vuoi (quindi anche letto dal file, ma ne parliamo dopo), ma quel costruttore di Automobili così come è scritto non ha alcun senso.
    semplicemente, come esercizio scolastico dobbiamo creare una classe automobili, con dei valori e dei metodi e poi usarli nel main. roba stupida.
    mi son voluto complicare la vita e fare la classe automobili molto articolata, e vorrei provare a simulare poi un concessionario, in maniera limitata, che vende auto usate e nuove. io ho postato solo una parte di codice, le variabili che te dici al momento devo ancora scrivere la parte di codice che la modificano, sto solo cercando di sistemare questo problema della marca al momento

    Ansharja ha scritto:


    A me sembra che qui serva un bel ripasso delle basi o, se ho capito male io quello che stai cercando di fare (anche perché il codice non è completo), cerca di spiegarti meglio (ma confermo che mi sembra tutto molto dubbio, e una riga come if (stato.equals("false")) è proprio una bestemmia).
    molto semplicemente, posso capire che è una bestemmia, ma non ho trovato altro modo per dire:
    1) dimmi casualmente se l'auto è nuova o usata
    2) true = nuova false = usata
    3) a me serve stampare lo stato della mia auto, ma se ci butto true e false magari chi lo vede non capisce
    4) con un if quindi assegno quello che esce dal random come stringa
    5) confronto la stringa, non so come altro fare se non con equals. e il codice dice il resto
    se in questo modo ho offeso voi programmatori esperti chiedo scusa, son ancora in fase di recupero dei concetti, e si mi diverto a giocare con cose nuove

    Ansharja ha scritto:


    Per quanto riguarda la lettura con Scanner, mi pare che tu abbia capito perché era sbagliato, tieni comunque presente che:
    
    while (reader.hasNextLine() == true)
    
    Andrebbe scritto come:
    
    while (reader.hasNextLine ()) // while (!reader.hasNextLine ()) se vuoi fare la negazione, che in questo caso non ha senso.
    
    Perché un valore boolean è già sufficiente per il test, non serve farne l'uguaglianza o meno con un altro boolean (in pratica staresti scrivendo if (true == true), o simili, quando ti basta if (true)).
    ok ti ringrazio, ho corretto

    Ansharja ha scritto:


    KuroKami69 ha scritto:


    Ok domanda che può sembrare molto stupida:
    perché con il for riesco a far uscire i dati dal cilo mentre con il while no?
    non credo centri la dichiarazione di i dentro al while no? alla fine è la stessa cosa del for

    edit:
    bhe effettivamente se dichiaro la i fuori dal while allora funziona...
    ma dichiararla nello statment del for oppure dentro al while, non è la stessa cosa?
    Se ti riferisci a questa parte di codice (ho solo corretto la condizione del while):
    
    while (reader.hasNextLine())
    {
       int i = 0;
       marche[i] = reader.nextLine(); //riempio il mio vettore leggendo da file
       i++;
       //return marche[i];
    }
    
    La variabile i viene inizializzata a 0 ad ogni iterazione, quindi stai sempre sovrascrivendo la stringa in marche [0].
    Quindi non è che con il while non si riesca a "far uscire i dati" dal ciclo.

    Se il for l'hai invece scritto in questo modo:
    
    for (int i = 0; reader.hasNextLine (); i ++)
    
    Questo vuol dire che i viene inizializzata a 0 subito prima di iniziare la prima iterazione, ma poi ad ogni iterazione viene incrementata, non ritorna a 0 ogni volta, quindi è ben diverso "dichiarare i nello statement del for oppure dentro al while", il for che ho scritto coincide appunto con il dichiarare i fuori dal while, e incrementarla ad ogni iterazione.
    ho capito il problema, effettivamente non ci avevo proprio fatto caso a questo dettaglio, ti ringrazio

    Ansharja ha scritto:


    KuroKami69 ha scritto:


    edit2:
    son riuscito a far funzionare anche il bufferedreader, anche se non capisco perché, mi prende solo 35 voci su 71...
    Il codice che stai usando:
    
    while (reader.readLine() != null)
    {
       int i = 0;
       marche[i] = reader.readLine(); //riempio il mio vettore leggendo da file
       i++;
       //return marche[i];
    }
    

    E' sbagliato, perché ad ogni iterazione leggi due righe (con reader.readLine ()), quindi ne butti via una delle due (quella che usi nella condizione del while).
    Quella riga invece va assegnata ad una variabile, altrimenti te la perdi. Il modo consueto per fare questo è il seguente:
    
    String line; // Dichiaro una variabile a cui verrà assegnata in loop ogni riga del file.
    while ((line = reader.readLine ()) != null) { // assegno a line il valore di reader.readLine (), e controllo che non sia uguale a null
    	// uso la variabile line, stavolta senza perdere nessuna riga.
    	// es. marche [i] = line; i ++;
    }
    
    in effetti prima avevo una variabile di appoggio, ma tra una modifica e l'altra è andata persa ahahaha *si vergogna* grazie mille

    Ansharja ha scritto:


    KuroKami69 ha scritto:


    edit3:
    perché il metodo:
    
    public String setMarcaRandom()
    {
    	int tmp = rng.nextInt(71);
    	marca = marche[tmp];
    	return marca;
    }
    

    della classe automobili (vedere primo post, c'è lo script completo) mi ritorna null? non ci arrivo proprio. in teoria gli sto dicendo:
    1) mi crei una variabile "temporanea" a cui assegni un random da 0 a 71
    2) mi assegni alla variabile marca, dichiarata all'inizio della classe, il valore nella posizione data da tmp del vettore marche
    3) mi ritorni la variabile modificata
    giusto no? o mi son perso qualche passaggio base?
    Quello che hai scritto è tecnicamente giusto (a parte il fatto che il numero random va da 0 a 70), bisogna vedere cosa contiene marche all'indice casuale che hai estratto, se la lettura da file non è corretta è possibile (anzi molto probabile) che in molti indici del vettore ci sia ancora il valore null.
    allora, vorrei fare una domanda. io ho il mio vettore marche[] pronto per essere usato
    
    private String marche[] = new String[71];
    
    se io gli assegno i valori tramite al while di prima, una volta uscito dal metodo, il mio array avrà dei valori?
    perché provando, non mi sembra proprio mmh
  • Re: Lettura da file

    Ho sostituito il while con il for da te scritto, il codice risulta molto più compatto rispetto al while dove dovevo creare la i fuori dal while e incrementarla nel while

    edit:
    effettivamente ora che ci penso bene il void non restituisce valori.
    di conseguenza mi viene cambiato il valore di marche nel metodo e basta, almeno secondo quanto sto vedendo ora..
    però se scrivo
    
    private void setMarca()
    {
    	marche[5] = "opel";
    }
    
    l'indice 5 di marche varrà opel no?

    quel while dovrebbe fare la stessa identica cosa di queste 2 righe di codice no?
  • Re: Lettura da file

    KuroKami69 ha scritto:


    semplicemente, come esercizio scolastico dobbiamo creare una classe automobili, con dei valori e dei metodi e poi usarli nel main. roba stupida.
    mi son voluto complicare la vita e fare la classe automobili molto articolata, e vorrei provare a simulare poi un concessionario, in maniera limitata, che vende auto usate e nuove. io ho postato solo una parte di codice, le variabili che te dici al momento devo ancora scrivere la parte di codice che la modificano, sto solo cercando di sistemare questo problema della marca al momento.
    Non credo che sia una roba stupida, gli esercizi servono sempre, anche se magari alcuni non sono il massimo. Comunque se pensi che la consegna sia rilevante e puoi/vuoi condividerla ci aiuteresti non poco.
    Non so appunto cosa ti è stato detto di fare, quello che dicevo in merito alle cose dubbie o un ripasso necessario era dovuto al fatto che la classe Automobili sembra proprio disegnata male, ma non perché sia molto articolata, il fatto è che contiene campi di istanza, come marca, che non dovrebbe avere, e da quello che mi pareva di capire anche i campi km, annoImmatricolazione, etc.
    Queste sono informazioni relative al singolo oggetto, come dicevo la soluzione più naturale sarebbe avere una classe Automobile con tutti questi campi, che vengono settati con un costruttore che sarà ad esempio invocato dalla classe Automobili.
    Questo perché Automobili ha tutta l'aria di essere la classe che si occupa appunto di gestire l'insieme degli oggetti, ha un vettore contenente le marche e sembra che tutto quel codice per ottenere valori casuali debba servire poi a istanziare un qualche oggetto, quindi non dovresti mischiare le due classi assieme. A meno che la consegna non dicesse di creare diversi oggetti di tipo Automobili, di cui ognuno abbia un diverso anno di immatricolazione, targa, etc., ma mi sembra molto forzato, poi se mi sbaglio dimmi pure, senza alcun problema.

    KuroKami69 ha scritto:


    molto semplicemente, posso capire che è una bestemmia, ma non ho trovato altro modo per dire:
    1) dimmi casualmente se l'auto è nuova o usata
    2) true = nuova false = usata
    3) a me serve stampare lo stato della mia auto, ma se ci butto true e false magari chi lo vede non capisce
    4) con un if quindi assegno quello che esce dal random come stringa
    5) confronto la stringa, non so come altro fare se non con equals. e il codice dice il resto
    se in questo modo ho offeso voi programmatori esperti chiedo scusa, son ancora in fase di recupero dei concetti, e si mi diverto a giocare con cose nuove.
    Il procedimento va anche bene (e ovviamente equals è il metodo corretto per fare il confronto tra stringhe) quello che dico io è che un informazione del tipo true/false è parecchio brutto memorizzarla all'interno di una stringa, per più ragioni, se poi vuoi che in base allo stato nuova/usata venga fornita una stringa diversa si può fare in molti modi, ma non a livello di memorizzazione della variabile, tutto qui.
    Non volevo farti una critica "da espertone", anche perché non lo sono proprio, mi scuso se ti ho dato questa impressione.

    KuroKami69 ha scritto:


    allora, vorrei fare una domanda. io ho il mio vettore marche[] pronto per essere usato
    
    private String marche[] = new String[71];
    
    se io gli assegno i valori tramite al while di prima, una volta uscito dal metodo, il mio array avrà dei valori?
    perché provando, non mi sembra proprio mmh
    Sì certo, marche è definito esternamente al metodo, quindi una volta usciti dal metodo mantiene i valori. Il fatto è che dal codice non si vede mai una chiamata al metodo che legge il file e assegna i valori a marche (nel tuo codice il metodo vettoreMarche ()), quindi prima di chiamare quel metodo marche contiene tutti null, a meno che ovviamente non sia modificato in altri posti. Senza vedere il tuo codice completo non si può dire se lo fai e dove, ricordati solo di richiamare il metodo vettoreMarche () prima di prenderne gli elementi (questo in sostanza risponde anche all'ultimo tuo messaggio).

    Per qualsiasi cosa, o se vuoi postare la consegna o più codice, siamo qui
  • Re: Lettura da file

    Ok
    io nel primo post avevo copiato parte del codice perché il codice completo comprende ancora molti metodi in costruzione
    comunque, spiego brevemente la consegna
    creare una classe automobili e una classe moto e simulare un concessionario di veicoli nuovi e usati
    i miei compagni sono un po' indietro quindi fanno semplicemente 2 classi, auto e moto con 4-5 attributi l'una i costruttori e i vari get e set e poi ci giocano nel main
    io invece, voglio usare molti valori per fare la cosa quanto più reale mi è possibile.
    vi copio l'intero codice della classe automibili, quello della classe moto ancora non c'è
    
    import java.util.Random;
    import java.util.Scanner;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    
    public class Automobili
    {
    	//definizione delle variabili della classe
    	//variabili generali ordinare prezzo
    	private String stato; //true è nuova, false è usata
    	private String marca;
    	private double prezzo;
    	//private String modello;
    	private String tipologia;
    	private String cambio;
    	private String trazione; //4x4, anteriore posteriore
    	private int marce;
    	private int cilindrata;
    	private int cilindri;
    	private double massaVuoto;
    	private String carburante;
    	private String colore;
    	private int nPosti;
    	private int nPortiere;
    	private int potenzaKw; //ordinare
    	private int cavalli;
    	private String targa;
    	private String consumo;
    	private String marche[] = new String[71]; //creo un vettore locale per le marche delle auto
    	private String tipo[] = new String[7]; //vettore tipologie
    	
    	//station vagon
    	private int bagagliaio; //litri
    	
    	//supersport
    	private double rapportoPesoPotenza; //supersport rapporto basso = buono
    
    	//per auto usate da ordinare.
    	private double km;
    	private int annoImmatricolazione;
    	private int scadenzaBollo; //accopiare a un if 2 anni
    	
    	//city car
    	private double lunghezza;
    	
    	//suv
    	private double altezzaTerra;
    	
    	//cabrio
    	private String tettuccio; //rigido o tela
    	
    	//oggetti di utilità
    	Random rng = new Random(); //costruttore dell'oggetto random
    	//BufferedReader reader = new BufferedReader(new FileReader("Automobili.txt")); //costruttore dell'oggetto reader, mi permette di leggere linee di testo nei file che gli passo
    	//String line = reader.readLine(fr()); //variabile di appoggio per la lettura del file di testo, da usare nel while
    
    		
    	//metodi di set
    	private String setStatoRandom() //metoto che mi dice in modo casuale se la mia auto è usata o meno
    	{
    		boolean tmp = rng.nextBoolean();
    		if (tmp == true) stato = "nuova";
    		else stato = "usata";
    		return stato;
    	}
    	
    	//riempio l'array marche[] con i valori letti dal file di testo
    	private void vettoreMarche()
    	{
    		try
    		{
    			Scanner reader = new Scanner(new FileReader("Automobili.txt")); //BufferedReader
    			for (int i = 0; reader.hasNextLine (); i++) //while (reader.hasNextLine()) //fino a quando non ritorna null (riga vuota) allora mi assegni un valore al vettore
    			{
    				marche[i] = reader.nextLine(); //riempio il mio vettore leggendo da file
    			}
    		}
    		catch (FileNotFoundException e)
    		{
    			System.out.println(e);
    			e.printStackTrace();
    		}
    	}
    	
    	//scelgo csualmente una mcarca di auto
    	private String setMarcaRandom()
    	{
    		int tmp = rng.nextInt(70);
    		marca = marche[tmp];
    		System.out.println(tmp);
    		return marca;
    	}
    	
    	/*setto il prezzo
    	private double setPrezzo()
    	{
    		//scelgo il prezzo dell'auto
    	}
    	
    	//scelgo casualmente una tipologia di automobile
    	private String setTipologia()
    	{
    		while (reader.readLine(fr("Tipologia.txt")) != null)
    		{
    			int i = 0;
    			tipo[i] = reader.readLine(fr("tipologia.txt"));
    			i++;
    		}
    	}
    	
    	//scelgo casualmente il tipo di cambio dell'auto
    	private boolean setCambio()
    	{
    		boolean tmp = rng.nextBoolean();
    		if (rng == true) cambio = "manuale";
    		else cambio = "automatico";
    	}
    	
    	//scelgo il tipo di trazione dell'auto
    	private String setTrazione()
    	{
    		//0 = 4x4, 1 = anteriore, 2 = posteriore
    		int tmp = rng = nextInt(2);
    		if (tmp == 0) trazione = "4x4";
    		else if (tmp == 1) trazione = "anteriore";
    		else trazione = "posteriore";		
    	}
    	
    	//scelgo il numero di marce dell'auto
    	private setMarce()
    	{
    		int tmp = rng.nextInt(6);
    		while (tmp < 5) tmp = rng.nextInt(6);
    		marce = tmp;
    	}
    
    	//calcolo la massa a vuoto
    	private double setMassaVuoto()
    	{
    		//calcolo massa a vuoto
    	}
    	
    	//calcolo il tipo di carburante
    	private String setCarburante()
    	{
    		//scelgo il tipo di carburazione
    	}
    	
    	//sclego random il colore dell'auto
    	private String setColore()
    	{
    		//generazione ascii colore
    		//conversione con variabile.decode("");
    	}
    	
    	//decdo il numero di posti della mia auto
    	private int setPosti()
    	{
    		//setto il numero di posti
    	}
    	
    	//decdo il numero di portiere della mia auto
    	private int setPortiere()
    	{
    		//setto il numero di portiere
    	}
    	
    	//setto la potenza in kw della mia auto
    	private int setPotenzaKw()
    	{
    		//setto la potenza in kw della mia auto
    	}
    	
    	//setto i cavalli della mia auto
    	private int setCavalli()
    	{
    		//imposto i cavalli della mia auto
    	}
    	
    	//creo la mia trga
    	private String setTarga()
    	{
    		//creo la mia targa
    		//numeri random
    		//lettere random
    	}
    	
    	//vedo il consumo della mia auto
    	private String setConsumo()
    	{
    		//calcolo il consumo
    	}
    	
    	//decido se il tettuccio della cabrio è rigido o in tela
    	private String setTettuccio()
    	{
    		//decido il materiale del tettuccio della cabrio
    	}
    	
    	//decido la lunghezza della city car
    	private double setLunghezza()
    	{
    		//deciso la lunghezza della mia city car
    	}
    	
    	//setto l'altezza da terra del mio suv
    	private double setAltezzaTerra()
    	{
    		//setto l'altezza da terra del mio suv
    	}
    	
    	//decido la dimensione del bagagliaio della station vagon
    	private int setBagagliaio()
    	{
    		//impostare la grandezza del bagagliaio in litri
    	}
    	
    	//decido il rapporto peso potenza della mia supersport
    	private double setRapportoPp(int peso, int cavalli)
    	{
    		//calcolare il rapporto peso potenza in
    	}
    	
    	//converto i cavalli in kw
    	private double conversioneCK(int c)
    	{
    		//conversione cavalli kw
    	}
    	
    	//converto i cavalli in kw
    	private double conversioneKC(int kw)
    	{
    		//conversione kw cavalli
    	}*/
    		
    	//metodo costruttore
    	public Automobili()
    	{
    		stato = setStatoRandom();
    		
    		if (stato.equals("false")) //attributi solo per le auto usate
    		{
    			km = 0.0;
    			annoImmatricolazione = 0;
    			scadenzaBollo = 0;
    			//targa = setTarga();
    		}
    		else //l'auto è nuova, non servon questi valori
    		{
    			targa = null;
    			km = 0.0;
    			annoImmatricolazione = 0;
    			scadenzaBollo = 0;
    		}
    		
    		marca = setMarcaRandom();
    		//prezzo = setPrezzo();
    		
    		/*switch (tipologia) //divide la tipologia dell'auto a seconda della marca che esce
    		{			
    			case "city car":
    				marche[0]; marche[1];
    				lunghezza = setLunghezza();
    				break;
    			
    			case "cabrio":
    				//?? si può mettere come case un filereader, che legge un file con vari valori e quei valori vengono tutti compresi nel case?
    				tettuccio = setTettuccioo();
    				break;
    			
    			case "coupe":
    				break;
    			
    			case "suv":
    				altezzaTerra = setAltezzaTerra();
    				break;
    			
    			case "berlina":
    				break;
    			
    			case "station vagon":
    				bagagliaio = setBagagliaio();
    				break;
    			
    			case "supersport":
    				rapportoPesoPotenza = setRapportoPp();
    				break;
    		}
    		
    		
    		cambio = setCambio();
    		trazione = setTrazione();
    		marce = setMarce();
    		massaVuoto = 0;
    		carburante = null;
    		colore = setColore();
    		nPosti = setPosti();
    		nPortiere = setPortiere();
    		potenzaKw = setPotenzaKw();
    		cavalli = setCavalli();
    		consumo = setConsumo();*/
    	}
    	
    	//get & set
    	public String getStato()
    	{
    		return stato;
    	}
    	
    	public String getMarca()
    	{
    		return marca;
    	}
    }
    
    allora, com'è strutturato ciò che voglio fare io?
    ho le mie classi automobili e moto (moto ancora da fare eh). dentro alla classe automobili dichiaro una serie di attributi ok?
    quando mi costruisco l'oggetto automobili nel main, io voglio farlo senza alcun passaggio di parametri, e con attributi scelti random, ma con un senso. fin qua è chiaro?
    per fare questo quindi cosa ho fatto? una serie di metodi private che vengono usati per impostare dinamicamente i valori random nel costruttore.
    per questo ci sono i km, annoimmatricolazione ecc nel costruttore
    il file salone.java non è ancora pronto al momento quindi non ho che 2 righe, creazione oggetto automobili e un system.out.println che mi ridà i 2 valori (al momento solo 2) dell'oggetto creato
    spero che la spiegazione sia sufficiente, ora ha più senso?

    scrivendo questa risposta ho capito perché lo script non funzionava come doveva.
    molto semplicemente dentro al metodo di selezione casuale della marca non avevo richiamato il metodo di creazione, che non veniva eseguito e quindi non mi faceva nessuna assegnazione all'array ahahahaha scusate
    comunque lascio il codice, magari se ho ancora bisogno non devo rifare tutto :3
  • Re: Lettura da file

    Via via che miglioro il codice effettivamente ho notato un sacco di cose inutili che ho sistemato. e continuando il processo eliminerò ancora molte cose
  • Re: Lettura da file

    Ho capito, ma é come temevo, hai voluto mischiare tutto assieme in un' unica classe.
    A mio parere qua da sistemare ci sarebbe molto, ma andremmo anche fuori tema e mi sembra che tu sia molto convinto di andare per questa strada

    Tieni presente comunque che in un programma "realistico", che tu poi potresti andare ad usare per qualcosa di più che non fare qualche prova, che avresti magari bisogno di modificare più volte, riutilizzare, o condividere, non puoi fare in questo modo.

    La tua classe di base dovrebbe essere il più possibile duttile, leggera e riutilizzabile, è davvero dura pensare che ogni volta che crei un' automobile, tutte le variabili siano scelte in modo casuale, che tu non possa avere dei costruttori semplici (anche con diverso numero di parametri) che dall' esterno possano anche essere chiamati con dati casuali, perché no, ma questo non dovrebbe deciderlo la singola Automobile!

    Comunque, per il proseguo del tuo programma, anche se vuoi continuare così, potresti comunque cercare di separare ciò che è proprio dell'automobile, da ciò che ti servirebbe anche per la tua classe Moto, parlo di costruire una classe che sia a un livello superiore (è il tipico esempio di Veicolo, Automobile, etc.) che raccoglierà variabili (ad esempio targa) e magari metodi in comune.

    Volendo potresti poi ulteriormente raffinare la gerarchia,visto che ti stai preoccupando di raccogliere informazioni per i casi SUV, berline o quant'altro, ma magari questo è un passo successivo.
  • Re: Lettura da file

    Grazie per la tua risposta ansharja.
    bhe questo esercizio è solo per esercitarmi, provare cose nuove e reimpostare la mia mente allo stato programmatore(neofita), cercando di scrivere codice pulito e funzionante.
    ma si hai ragione, qualora volessi creare un programma di questo tipo, ma serio, andrei a leggere i vari dati da db e restituirei dei valori predefiniti, senza sbattermi tanto con cose tanto "complicate" quanto inutili.
    l'idea di fare una superclasse e 2 classe specializzatrici (non ho ancora imparato bene la nomeclatura, spero di essermi spiegato) mi era passata per la testa ma non è ancora il momento, magari quando avrò finito questa classe, e che funzionerà tutto, allora farò il passo successivo che hai suggerito
    sarei molto interessato a capire cosa secondo te ci sarebbe da sistemare, quindi se vuoi scriverlo qua o anche in privato, va bene
    piccola domandina fuori tema
    con la funzione nextInt dello scanner, mi legge TUTTI i valor numerici interi in un documento oppure solo quelli su una riga?
    perché con il metodo readline e con l'uso di split della classe String, mi ero fatto una bella matrice partendo dalle marche dell'auto e inserendo un index da usare per il prezzo e la tipologia. volevo capire se è possibile fare lo stesso con il metodo nextInt
  • Re: Lettura da file

    Quello che io cambierei te l'ho già detto qua e là negli altri post ... Sicuramente il codice che hai postato è tutt'altro che pulito per ora, anzi direi il contrario.

    Io comincerei dalle basi, rispettando le convenzioni: nome singolare per una classe che rappresenta un singolo oggetto (Automobile, sempre che non vada contro la consegna, il che mi pare assurdo comunque), metodi set usati a proposito (i set e get sono metodi particolari che chiunque legge interpreta in un certo modo, in particolare il set in genere restituisce void, ma soprattutto prende in ingresso il parametro da impostare al campo corrispondente, e non ha gran senso di essere private, non vuoi avere oggetti immutabili o altro), tipi di variabili "corretti" (sempre riferito a stato, se vuoi inserirci "true" o "false" dentro, perché non usare una variabile boolean chiamata ad esempio nuova (o usata), con un metodo isNuova () che è molto più facilmente interpretabile, e se serve nel toString (), o in un altro metodo, es. getDescrizione (), ritornare una stringa formattata come ti pare e piace, es. "Macchina nuova, targa ...", che è più chiaro di "true" o false" in stringa) ...

    Poi appunto, oltre a cercare di astrarre qualcosa a un livello superiore di Automobile, e magari specializzarla in altre classi, io sposterei tutta la logica di lettura del file (a proposito, un case con un filereader non si può fare, ma per fortuna, sarebbe un orrore) in una classe esterna a quella che modella la singola auto, che sia Concessionario o altro (e non dico affatto che non vada bene l'idea di creare auto in modo causale, leggere le marche da file, ma solo di non delegarlo alla stessa classe), mischiare i compiti delle classi ti crea solo problemi e casino ...

    Comunque per venire alla tua domanda, nextInt () legge solo il successivo "token" dell'input convertendolo in intero (se possibile, altrimenti lancia un InputMismatchException), quindi legge molto meno di una riga, dovresti perlomeno usarlo in loop, ma bisogna vedere come è fatto il file.
    In linea generale readLine () e split () mi sembrano metodi più appropriati per fare quello che ti serve, non ho capito invece a cosa ti serva un indice per prezzo e tipologia, non dovrebbe essere necessario se il carattere per splittare la stringa è sempre lo stesso e il file è ben formato ...
  • Re: Lettura da file

    Ah ma il codice è stato parecchio modificato xD ora è diverso
    quei metodi, is etc non li abbiamo mai fatti e io personalmente non li ho mai visti quindi non so bene come funzionano.
    invece per il fatto dell'indicie del presso, bhe semplicemente:
    ho un metodo che riempie la matrice delle marche e a ogni marca corrisponde una tipologia (city car, berlina etc), e un indice, in questo modo io per esempio avrò una matrice[71][3], che ad esempio, su marche[5][0], avrò "aston martin", su marche[5][1] avràò "supersport" e invece su marche[5][2] avrò 6, così quando vado a creare il metodo per settare un prezzo random alla mia macchina, esso si baserà sulla tipologia dell'auto stessa, e uso l'indice per andare direttamente con la matrice marche dentro all'indice della matrice scaglioni (di prezzo) e costruirmi così un numero random
    ed esc eun codice simile
    prezzo = rng.nextInt((scaglioni[marche[idx][2]][1] - scaglioni[marche[idx][2]][0]) + scaglioni[marche[idx][2]][0]);
    ok forse se non metto anche il codice precedente ha poco senso giusto? era solo per mostrare come setto il prezzo
    magari cambierò i vari nomi come mi hai consigliato.
    per i metodi, è giusto uno sfizio, li ho chiamati set per vedere a occhio a cosa servon e il fatto che li rendo privati perché voglio che vengano usati solo in un unica occasione, quindi non ha senso dargli la possibilità di venire richiamati fuori no?
    poi a me han sempre insegnato che in genere un set si costruisce sul nome della variabile, per esempio, se io volessi modificare la marca della mia auto, allora farei un metodo setMarca();, come l'ho fatto io indica che vado a impostare un valore random deciso dal sistema.
    ok è notte son stanco e forse questa risposta è un po' incasinata ahaha
    volevo chiedere, readLine() mi restituisce una stringa no, quindi in questo caso, metti che legge la prima riga di scaglioni di prezzo, mi restituirà, ad esempio, 5000 e 15000, come stringhe però giusto? se volessi convertirli in int mi basta fare un semplice integer.parseint?
  • Re: Lettura da file

    KuroKami69 ha scritto:


    quei metodi, is etc non li abbiamo mai fatti e io personalmente non li ho mai visti quindi non so bene come funzionano.
    Quel nome che ho scritto al volo, isNuova, è solo il nome che si dà per convenzione a un metodo getter che restituisce il valore di un campo booleano, se il campo booleano si chiama nuova, non si usa getNuova ma isNuova (ovviamente in italiano rende meno ). Più che il nome del metodo è importante il concetto di usare il tipo corretto comunque.

    KuroKami69 ha scritto:


    invece per il fatto dell'indice del prezzo, beh semplicemente:
    ho un metodo che riempie la matrice delle marche e a ogni marca corrisponde una tipologia (city car, berlina etc), e un indice, in questo modo io per esempio avrò una matrice[71][3], che ad esempio, su marche[5][0], avrò "aston martin", su marche[5][1] avrò "supersport" e invece su marche[5][2] avrò 6, così quando vado a creare il metodo per settare un prezzo random alla mia macchina, esso si baserà sulla tipologia dell'auto stessa, e uso l'indice per andare direttamente con la matrice marche dentro all'indice della matrice scaglioni (di prezzo) e costruirmi così un numero random
    ed esc eun codice simile
    prezzo = rng.nextInt((scaglioni[marche[idx][2]][1] - scaglioni[marche[idx][2]][0]) + scaglioni[marche[idx][2]][0]);
    ok forse se non metto anche il codice precedente ha poco senso giusto? era solo per mostrare come setto il prezzo.
    Chiaro, però il modo in cui lo fai è molto rischioso, hai poco controllo sui valori che vai a prendere, forse sarebbe utile ragionare anche qui "a oggetti" e creare una classe apposta per il range di prezzi, in questo caso una mappa sarebbe (penso) una buona via per associare la marca o la tipologia di auto alla relativa fascia di prezzo, ma ho solo un'idea a grandi linee di quello che vuoi fare.

    KuroKami69 ha scritto:


    per i metodi, è giusto uno sfizio, li ho chiamati set per vedere a occhio a cosa servono e il fatto che li rendo privati perché voglio che vengano usati solo in un unica occasione, quindi non ha senso dargli la possibilità di venire richiamati fuori no?
    poi a me han sempre insegnato che in genere un set si costruisce sul nome della variabile, per esempio, se io volessi modificare la marca della mia auto, allora farei un metodo setMarca();, come l'ho fatto io indica che vado a impostare un valore random deciso dal sistema.
    Certo, è chiaro quello che vuoi fare, dico solo che non è così che si comporta un metodo set di solito, se poi aggiungi dei metodi set tradizionali magari cambia i nomi di quei metodi, che fanno un po' di confusione.

    KuroKami69 ha scritto:


    volevo chiedere, readLine() mi restituisce una stringa no, quindi in questo caso, metti che legge la prima riga di scaglioni di prezzo, mi restituirà, ad esempio, 5000 e 15000, come stringhe però giusto? se volessi convertirli in int mi basta fare un semplice integer.parseint?
    Sì, tutto giusto, è a tuo carico interpretare correttamente i dati che acquisisci, e preoccuparti che i valori siano "corretti". Quando fai la lettura del file sarebbe una buona idea utilizzare un blocco try catch per gestire in bel modo i possibili errori, in modo che sei tu a decidere cosa succede in caso che ci sia una stringa che non può essere convertita in numero nel posto sbagliato, che ci sia un dato mancante o altro (potresti voler che il programma si interrompa con un messaggio d'errore che avverte che il file è malformato, o bloccare la lettura e mantenere ciò che hai letto fino a quel punto, o ignorare solo la singola riga e passare alla successiva, ...)
  • Re: Lettura da file

    Ah è tutto chiaro. allora ho già un'idea di come sarà il metodo. è che avevo visto anche metodi tipo isBoolean e questo mi ha portato a credere che fossero una funzione integrata di qualche libreria. ma onestamente non volevo fare mille metodi, non son ancora pratico di progettazione e ora volevo concentrarmi un attimino sul fare codice. chiaramente devo anche compensare le infinite carenze che ho ma piano piano, la mia filosofia è: imparare facendo"... quindi magari quando finirò questo farò un altro esercizio e lo strutturerò meglio, ma intanto con questo mi faccio un'idea che poi migliorerò con il prossimo. diciamo che questa è una v0 del mio essere programmatore, non so se mi son spiegato.
    essendo questo solo un esempio che deve solo creare una serie di auto con dei valori random, li vede poi visualizzare in una tabella. al massimo implementerò l'ordinamento per prezzo, tipo, e altre robette così, masarà da dichiarare all'esecuzione dello script. non stiamo lavorando ancora con le interfacce (layout giusto? si le interfacce sono anche un'altra cosa da quello che so, ma io intendo l'interfaccia grafica) e magari però le userò nel prossimo esercizio dando più libertà all'utente e magari migliorerò anche questo con alcune implementazioni
Devi accedere o registrarti per scrivere nel forum
21 risposte