Visualizzazione dei risultati da 1 a 2 su 2

Discussione: Leggere un file

  1. #1

    Leggere un file

    Ciao a tutti, in un programma che devo implementare mi viene richiesto di leggere da un file una serie di preventivi, ognuno dei quali contiene i seguenti dati: progressivo delpreventivo, data, codice fiscale del richiedente, tasso di sconto applicato, lista di mobili, ciascuno accompagnato dalla tipologia (lusso, rustico, economico, ...), dalla quantità, e dal relativo prezzo, chiusa dal simbolo '#', in questo modo:


    1
    12/01/2005
    VRDPLA87T65H456O
    30
    tavolo
    lusso
    1
    5000.00
    sedia
    lusso
    6
    500.00
    #
    2
    14/01/2005
    RSSMRA56I98J314K
    20
    comodino
    rustico
    2
    450.00
    letto
    rustico
    1
    2000.00
    #
    ...
    10
    20/02/2005
    VRDPLA87T65H456O
    30
    console
    lusso
    1
    3500.00
    #
    .....


    io ho implementato le seguenti classi:
    CLASSE MOBILE
    codice:
    import java.io.PrintStream;import java.util.Scanner;
    
    
    public class Mobile 
    {
        private String tipo;
        private int quantita;
        private double prezzo;
        private String mobile;
        
        public Mobile(String mobile, String tipo, int quantita, double prezzo) 
        {
            this.tipo = tipo;
            this.quantita = quantita;
            this.prezzo = prezzo;
            this.mobile = mobile;
        }
    
    
        public String getMobile(){
            return mobile;
        }
        
        public String getTipo() {
            return tipo;
        }
    
    
        public int getQuantita() {
            return quantita;
        }
    
    
        public double getPrezzo() {
            return prezzo;
        }
    
    
        public void setPrezzo(double prezzo) {
            this.prezzo = prezzo;
        }
        
        public static Mobile read(Scanner s)
        {
            if(!s.hasNextLine())
                return null;
            String mobile = s.nextLine(); 
            
            if(!s.hasNextLine())
                return null;
            String tipo = s.nextLine();
            
            if(!s.hasNextLine())
                return null;
            int quantita = Integer.parseInt(s.nextLine());
            
            if(!s.hasNextLine())
                return null;
            double prezzo = Double.parseDouble(s.nextLine());
            
            return new Mobile(mobile, tipo,quantita,prezzo);
        }
        
        public void print(PrintStream ps) {
            ps.println(mobile);
            ps.println(tipo);
            ps.println(quantita);
            ps.println(prezzo);
        }
        
    }
    CLASSE CLIENTE
    codice:
    import java.io.PrintStream;import java.util.ArrayList;
    import java.util.Scanner;
    
    
    
    
    public class Cliente 
    {
        private String cf;
        private String nome;
        private String cognome;
        private String indirizzo;
        private ArrayList<Preventivo> preventivi;
        
        public Cliente(String cf, String nome, String cognome, String indirizzo) 
        {
            this.cf = cf;
            this.nome = nome;
            this.cognome = cognome;
            this.indirizzo = indirizzo;
            preventivi = new ArrayList<Preventivo>();
        }
    
    
        public String getCf() {
            return cf;
        }
    
    
        public String getNome() {
            return nome;
        }
    
    
        public String getCognome() {
            return cognome;
        }
    
    
        public String getIndirizzo() {
            return indirizzo;
        }
    
    
        public ArrayList<Preventivo> getPreventivi() {
            return preventivi;
        }
    
    
        public void setPreventivi(ArrayList<Preventivo> preventivi) {
            this.preventivi = preventivi;
        }
        
        public void addPreventivo(Preventivo p)
        {
            preventivi.add(p);
        }
        
        public static Cliente read(Scanner in)
        {
            if(!in.hasNextLine())
                return null;
            String cf = in.nextLine();
            
            if(!in.hasNextLine())
                return null;
            String nome = in.nextLine();
            
            if(!in.hasNextLine())
                return null;
            String cognome = in.nextLine();
            
            if(!in.hasNextLine())
                return null;
            String indirizzo = in.nextLine();
            
            return new Cliente(cf,nome,cognome,indirizzo);
        }
        
        public void print(PrintStream ps)
        {
            ps.println(cf);
            ps.println(nome);
            ps.println(cognome);
            ps.println(indirizzo);
        }
    }
    CLASSE PREVENTIVO
    codice:
    import java.util.Date;import java.io.PrintStream;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Scanner;
    
    
    public class Preventivo 
    {
        private String id;
        private Date data;
        private String cf;
        private int sconto;
        private ArrayList<Mobile> mobili;
        private Cliente cliente;
        
        public Preventivo(String id, Date data, String cf, int sconto, ArrayList<Mobile> mobili) {
            super();
            this.id = id;
            this.data = data;
            this.cf = cf;
            this.sconto = sconto;
            this.mobili = mobili;
            cliente = null;
        }
    
    
        public String getId() {
            return id;
        }
    
    
        public Date getData() {
            return data;
        }
    
    
        public String getCf() {
            return cf;
        }
    
    
        public int getSconto() {
            return sconto;
        }
    
    
        public ArrayList<Mobile> getMobili() {
            return mobili;
        }
    
    
        public Cliente getCliente() {
            return cliente;
        }
    
    
        public void setSconto(int sconto) {
            this.sconto = sconto;
        }
    
    
        public void setMobili(ArrayList<Mobile> mobili) {
            this.mobili = mobili;
        }
        
        public void setCliente(Cliente cliente) {
            this.cliente = cliente ;
        }
        
        public void preventivoScontato()
        {
            ArrayList<Mobile> mobiliScontati = new ArrayList<Mobile>();
            for(Mobile m: mobili)
            {
                double prezzoScontato = ((m.getPrezzo()/100)*(100 - sconto));
                m.setPrezzo(prezzoScontato);
                mobiliScontati.add(m);
            }
            this.setMobili(mobiliScontati);
        }
        
        public static Preventivo read(Scanner s)
        {
            Date data;
            ArrayList<Mobile> mobili = new ArrayList<Mobile>();
            
            if(!s.hasNextLine())
                return null;
            String id = s.nextLine();
            
            SimpleDateFormat df = new SimpleDateFormat(Constants.FormatDate); 
            
            if(!s.hasNextLine())
                return null;
            try {
                data = df.parse(s.nextLine());
            } catch (ParseException e) {
                System.err.println("Un'eccezione è stata lanciata nella lettura del progetto " + id);
                System.err.println("Verrà assegnata di default la data odierna");
                data = new Date();
            }
            
            if(!s.hasNextLine())
                return null;
            String cf = s.nextLine();
            
            if(!s.hasNextLine())
                return null;
            int sconto = Integer.parseInt(s.nextLine());
            
            boolean done = true;
            if(!s.hasNextLine())
                return null;
            while(done){
                mobili.add(Mobile.read(s));
                if(s.nextLine().equals("#")) done = false;
                else done = true;
            }
            
            return new Preventivo(id,data,cf,sconto,mobili);
        }
        
        public void print(PrintStream ps) {
            SimpleDateFormat df = new SimpleDateFormat(Constants.FormatDate);
    
    
            ps.println(id);
            ps.println(df.format(data));
            ps.println(cf);
            ps.println(sconto);
            for(Mobile m: mobili)
                ps.println(m);
        }
        
        public void addMobile(Mobile m)
        {
            mobili.add(m);
        }
        
    }
    CLASSE ARCHIVIO
    codice:
    import java.io.PrintStream;import java.util.ArrayList;
    import java.util.Scanner;
    
    
    public class ArchivioPreventivi 
    {
        private ArrayList<Preventivo> preventivi;
        private ArrayList<Cliente> clienti;
    
    
        public ArchivioPreventivi(Scanner sP, Scanner sC)
        {
            clienti = new ArrayList<Cliente>();
            while(sC.hasNextLine())
            {
                Cliente c1 = Cliente.read(sC);
                clienti.add(c1);
            }
            
            preventivi = new ArrayList<Preventivo>();
            Cliente c = null;
            while(sP.hasNextLine())
            {
                try{
                    Preventivo p = Preventivo.read(sP);
                    c = this.searchClienteByCodFiscale(p.getCf());
                    
                    p.setCliente(c);
                    c.addPreventivo(p);
                    
                    preventivi.add(p);
                }catch(ClienteNotFoundException e)
                {
                    System.err.println(e.getMessage());
                    System.err.println("La connessione non verrà effettuata ");
                }
            }
        }
        
        private ArchivioPreventivi(ArrayList<Preventivo> preventivi, ArrayList<Cliente> clienti)
        {
            this.preventivi = preventivi;
            this.clienti = clienti;
        }
        
        public Cliente searchClienteByCodFiscale(String cf) throws ClienteNotFoundException
        {
            Cliente cliente = null;
            for(Cliente p: clienti)
                if(p.getCf().equals(cf))
                    cliente = p;
            if(cliente == null)
                throw new ClienteNotFoundException("Cliente non trovato per il codice fiscale " + cf); 
            
            return cliente;
        }
        
        public ArrayList<Preventivo> searchPreventiviByNameSurnameCliente(String name, String surname)
        {
            ArrayList<Preventivo> preventiviCercati = new ArrayList<Preventivo>();
            for(Preventivo p: preventivi)
            {
                Cliente c = p.getCliente();
                if(c.getNome().equalsIgnoreCase(name) && c.getCognome().equalsIgnoreCase(surname)){
                    p.preventivoScontato();
                    preventiviCercati.add(p);
                }
            }
            return preventiviCercati;
        }
        
        public ArrayList<Preventivo> preventiviScontati()
        {
            ArrayList<Preventivo> preventiviScontati = new ArrayList<Preventivo>();
            for(Preventivo p: preventivi)
            {
                p.preventivoScontato();
                preventiviScontati.add(p);
            }
            return preventiviScontati;
        }
        
        public void print(PrintStream ps)
        {
            for(Preventivo p: preventivi)
                p.print(ps);
        }
    
    
    }
    Quando eseguo il programma di test, mi lancia un'eccezione di tipo NumberFormatException quando va a leggere i mobili. Non riesco a capire dove stia l'errore

  2. #2
    Utente di HTML.it
    Registrato dal
    Oct 2014
    residenza
    Padova
    Messaggi
    361
    Magari la questione della NumberFormatException l'avrai già risolta, nel tuo codice solo Integer.parseInt e Double.parseDouble possono causare quell'eccezione, quando la stringa che tentano di parsare non contiene un numero del tipo desiderato.
    E questo è un caso che dovresti considerare, a differenza di quanto potresti fare magari se richiedessi esplicitamente un input numerico da tastiera.

    Ti consiglio quindi di usare un blocco try-catch per quando devi fare il parsing da stringa a numero.
    Magari (anzi meglio) al di fuori del metodo read in Mobile (che abbiamo già detto dovrebbe essere in una classe esterna, non mischiare le classi Preventivo, Mobile etc. con la lettura da file, crea una o più classi apposite separate).

    Il metodo read potrebbe solo lanciare all'esterno l'eccezione , sarà il chiamante a doversene occupare e scegliere cosa fare.
    In questo modo eviti anche di dover restituire un oggetto Mobile null come valore di ritorno in caso di errore.
    Potresti anche evitare di passare lo Scanner in giro per i metodi, e mantenere lo Scanner localizzato solo nel metodo dove leggi il file.

    Ad esempio quel metodo read di Mobile potresti scriverlo come :

    codice:
    public static Mobile read (String mobile, String tipo, String quantita, String prezzo) throws Exception
    {
        if (mobile == null || tipo == null || quantita == null || prezzo == null) throw new IllegalArgumentException ("Non sono ammessi valori null"); 
        return new Mobile (mobile, tipo, Integer.parseInt (quantita), Double.parseDouble (prezzo));
    }
    I controlli poi li puoi fare approfonditi quanto ti pare.

    Il punto è che in questo caso read riceve le stringhe da "convertire in un Mobile" e prova a restituire l'oggetto, se una stringa è null o non contiene un numero come dovrebbe, viene lanciata all'esterno un'eccezione, senza dover restituire null.

    Quel throws Exception nella dichiarazione, che in questo caso non sarebbe strettamente necessario visto il tipo delle eccezioni, costringe il chiamante di read a gestire l'eccezione (o a ridichiararla).

    Chi chiama read quindi potrebbe quindi fare qualcosa del genere :

    codice:
    // lo scanner in è stato creato in precedenza e sei arrivato al punto del file in cui devi leggere i dati di un mobile, magari in un ciclo.
    try {
        Mobile mobile = read (in.nextLine (), in.nextLine (), in.nextLine (), in.nextLine ());
    }
    catch (Exception e) {
        // Il file non contiene dati corretti, scegli come comportarti, se continuare la lettura, interromperla o quant'altro.
    }
    Nota che puoi (in alcuni casi sarebbe meglio) catturare le eccezioni separatamente, in questo caso un'eventuale IllegalArgumentException (a seguito di un valore null) o una NumberFormatException (per una stringa non numerica) verrebbero entrambe considerate in un unico blocco catch.

    In questo caso ho considerato la lettura di un blocco di 4 righe assieme, senza controllare che le righe siano effettivamente presenti, aspettandomi che il file sia ben formato, da qualche parte dovrai comunque controllare che il file non sia finito.

    Ci potrebbero essere tante altre cose da dire, magari anche pareri diversi, io imposterei la lettura in questo modo

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.