330 likes | 517 Views
I/O elementare. Java. IO elementare. Prof. Francesco Bellotti ELIOS Lab - DIBE – The University of Genoa. Il package java.io. Il linguaggio Java non ha istruzioni (statement) standard per fare l’input e output I/O fatto attraverso metodi (funzioni) che sono parte di un package
E N D
I/O elementare Java IO elementare Prof. Francesco Bellotti ELIOS Lab - DIBE – The University of Genoa
Il package java.io • Il linguaggio Java non ha istruzioni (statement) standard per fare l’input e output • I/O fatto attraverso metodi (funzioni) che sono parte di un package • Un package è una collezioni di classi che offrono funzionalità usabili da altri programmi • Un package è come una scatola degli attrezzi con le classi che sono gli attrezzi • Per fare l’I/O di base usiamo il package java.io, che è il più semplice • Ne esistono anche altri più specialistici
I/O streams • In Java, una sorgente di dati di input è detta un input stream e i dati in uscita sono detti output stream • In generale, un programma può avere più stream di input e di output • Per iniziare, ueseremo 3 semplici stream di IO • System.in — lo stream di input • System.out — lo stream di output normale • System.err — lo stream di output per i messaggi di errore • System.in è tipicamente collegato alla tastiera e i dati sono caratteri • System.out e System.err sono collegati al monitor e i dati sono sempre caratteri
Esempio di IO import java.io.*; class Echo { public static void main (String[] args) throws IOException { //Analizzeremo in seguito queste 2 linee. //Per ora consideriamole necessarie per creare //l’oggetto stdin usato per leggere da tastiera InputStreamReader inStream = new InputStreamReader( System.in ) ; BufferedReader stdin = new BufferedReader( inStream ); String inData; System.out.println("Enter the data:"); //legge una riga di codice dalla tastiera inData = stdin.readLine(); System.out.println("You entered:" + inData ); } } C:\users\default>java Echo Enter the data: This is what the user enters You entered:This is what the user enters C:\users\default>
Analizzando il programma • import java.io.*; • avverte il compilatore di usare il package java.io • Il simbolo * significa che ogni classe di quel package potrebbe essere usata • throws IOException • E’necessaria per programmi che fanno input (almeno per ora) • Informa il compilatore che il metodo main() potrebbe fallire • Se main() dovesse fallire, la Java Virtual Machine che interpreta il programma Java gestirà una “accettabile” chiusura del programma • Le eccezioni (situazioni di possibile errore) o vengono gestite localmente in un metodo, oppure vengono rilanciate dal metodo ad altri metodi (i metodi chimanti) o alla virtual machine (come appunto in questo caso)
Creazione dell’oggetto per leggere da tastiera • La variabile inStream è usata solo per connettere l’InputStreamReader al BufferedReader • InputStreamReader inStream = new InputStreamReader( System.in ) ; • BufferedReader stdin = new BufferedReader( inStream ); • Si può semplificare il codice scrivendo una sola riga • BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
Convertire stringhe di caratteri in valori numerici • Usando il programma Echo, se si inseriscono da tastiera dei valori numerici, questi sono letti come caratteri • Verificalo! • E se voglio leggere dei numeri? • Devo trasformare i caratteri in numeri • Usando i metodi della classe Integer, che è il wrapper del tipo int
Lettura di valori numerici import java.io.*; class EchoSquare { public static void main (String[] args) throws IOException { BufferedReader stdin = new BufferedReader (new InputStreamReader(System.in)); String inData; int num, square; // declare two int variables System.out.println("Enter an integer:"); inData = stdin.readLine(); num = Integer.parseInt( inData ); // convert inData to int square = num * num ; // compute the square System.out.println("The square of " + inData + " is " + square); } }
Convertire stringhe di caratteri in valori numerici • Ovviamente, si può anche scrivere il valore direttamente nell’argomento • num = Integer.parseInt( "39" ); • E se l’utente del programma scrivesse un intero in formato sbagliato? • 134 -45 • Sono ok • 1 4 9 2 14.92 centotrentquattro “ 134” • Sono sbagliati • Lo statement inData = stdin.readLine() non darebbe alcun problema • Ma num = Integer.parseInt( inData ) non sarebbe in grado di interpretare la sequenza come un intero • Il metodo parseInt() lancia un’eccezione di tipo NumberFormatException Enter an integer: 14.92 java.lang.NumberFormatException: 14.92
Esempio: somma di 2 interi import java.io.*; class AddTwo { public static void main (String[] args) throws IOException { BufferedReader stdin = new BufferedReader ( new InputStreamReader( System.in ) ); String line1, line2; // declaration of input Strings int first, second, sum ; // declaration of int variables System.out.println("Enter first integer:"); line1 = stdin.readLine(); first = Integer.parseInt( line1 ); // convert line1 to first int System.out.println("Enter second integer:"); line2 = stdin.readLine(); second = Integer.parseInt( line2 ); // convert line2 to second int sum = first + second; // add the two ints, put result in sum System.out.println("The sum of " + first + " plus " + second +" is " + sum ); } }
Esercizi di programmazione • Riscrivi il programma in modo che poduca lo stesso output, ma senza usare nel println finale né la variabile first né la variabile second • Scrivere un programma simile al precedente, che riceva dall’utente i valori di un dividendo e di un divisore interi e produca in output i risultati della divisione e del resto
Esercizi di programmazione • Scrivere un programma che legga un numero di centesimi e scriva il numero di Euro e centesimi • D:\users\default>java Dollars • Inserisci il numero di centesimi: 324 • Sono 3 euro e 24 centesimi • Usa aritmetica intera e non floating point! • If(num>100) • num = 24 • else • num=0;
Esercizi di programmazione • Il resto giusto • Scrivere un programma che prenda in ingresso un numero di centesimi da restituire al cliente e produca in uscita il numero di monete da: 2 e 1 Euro, e da 50, 20, 10, 5, 2 e 1 centesimi da dare al cliente • Usa aritmetica intera e non floating point!
Input floating point import java.io.*; class StringToDouble { public static void main (String[] args) { final String charData = "3.14159265"; double value; value = Double.parseDouble( charData ) ; System.out.println("value: " + value +" twice value: " + 2*value ); } } • Cambierebbe qualcosa se togliessi le virgolette dall’inizializzazione di charData? • E se invece usassimo la notazione scientifica? • final String charData = "0.314159265E+1";
Input floating point da tastiera import java.io.*; class InputToDouble { public static void main (String[] args) throws IOException { String charData; double value; BufferedReader stdin = new BufferedReader (new InputStreamReader(System.in)); System.out.println("Enter a double:"); charData = stdin.readLine(); value = Double.parseDouble( charData ) ; System.out.println("value: " + value +" twice value: " + 2*value ); } }
Il costo di una cena… import java.io.*; class RestaurantBill { public static void main (String[] args) throws IOException { String charData; double basicCost; BufferedReader stdin = new BufferedReader ( new InputStreamReader( System.in ) ); System.out.println("Enter the basic cost:"); charData = stdin.readLine(); basicCost = Double.parseDouble( charData ) ; System.out.println("basic cost: " + basicCost + " total cost: " + (basicCost + basicCost*0.06 + basicCost*0.20)); } } • Il costo di una cena è dato dal costo di base (inserito dall’utente) + il 6% di tasse e il 20% di servizio
Esercizio di programmazione • Modificare il programma precedente così che l’utente possa inserire da tastiera le percentuali per le tasse e il servizio
Java come una calcolatrice… import java.io.*; class SquareRoot { public static void main (String[] args) throws IOException { String charData; double value; // read in a double BufferedReader stdin = new BufferedReader (new InputStreamReader(System.in)); System.out.print ("Enter a double:"); charData = stdin.readLine(); value = Double.parseDouble( charData ) ; // calculate its square root double result = Math.sqrt( value ); // write out the result System.out.println("square root: " + result ); } }
La classe Math • La classe Math ha molti metodi che possono tornare utili… • Es: log, sin, cos • Provali per esercizio • Vuoi saperne di più sulla classe Math? • Controlla la documentazione Java online: java.sun.com oppure sul tuo java sdk! • Sqrt è descritto così: static double sqrt(double a) • Qual è il tipo di input? E quale quello di output? • Prova l’esercizio precedente con vari input • Es. 3.5, 9.0, 9, -4, etc.
Conversione automatica di tipo • Sqrt() si aspetta un double come parametro di ingresso. Tuttavia il codice funziona anche se noi gli passiamo un intero • Il compilatore inserisce automaticamente il codice per la conversione al tipo giusto • Alla chiamata di sqrt() il parametro passato è di tipo double • Spesso i programmatori usano un cast esplicito: int x = 9; System.out.println( Math.sqrt( (double)x ) ); • Come detto, in questo caso il cast non era richiesto • Qual è il risultato di questo frammento? int x = 1; int y = 9; System.out.println( Math.sqrt(x/y) ) ); • Il risultato è 0.0, forse non quello che ci saremmo aspettati. Come possiamo risolvere la cosa? • Con un cast esplicito
Math.cos() e Math.sin() vogliono radianti… • Ma noi siamo abituati a ragionare in gradi… • Usiamo le funzioni di Math • public static double toRadians(double angdeg) • public static double toDegrees(double angrad) import java.io.*; class CosineCalc { public static void main (String[] args) throws IOException { String charData; double degrees; // read in a double BufferedReader stdin = new BufferedReader (new InputStreamReader(System.in)); System.out.print ("Enter degrees:"); charData = stdin.readLine(); degrees = Double.parseDouble( charData ) ; // calculate its cosine double result = Math.cos( Math.toRadians(degrees) ); //Nota le funzioni annidate // write out the result System.out.println("cosine: " + result ); } }
Esercizi di programmazione • Scrivere un programma che calcola la velocità (ad un istante che l’utente specifica in input) di un oggetto lasciato cadere da una torre • Usa la formula: v = (1/2) g t2 • Scrivere un programma che il logaritmo in base 2 di un numero specificato dall’utente • Ricorda: log2 X = (loge X) / (loge 2)
Esercizi di programmazione • Scrivere un programma che legge da input 2 numeri e ne produce la media aritmetica e la media armonica • Formula per la media armonica:H = 2 / ( 1/X + 1/Y )
La gerarchia di classi di java.io • 2 gerarchie di classi principali • Basate sul tipo di dato su cui operano • Character streams (16 bit) • Java.io.Reader e java.io.writer sono le superclassi abstract • Byte streams (8 bit) • Java.io.InputStream e java.io.OutputStream
Reading and writing… Reader InputStream int read()int read(char cbuf[])int read(char cbuf[], int offset, int length) int read()int read(byte cbuf[])int read(byte cbuf[], int offset, int length) Writer OutputStream int write(int c)int write(char cbuf[])int write(char cbuf[], int offset, int length) int write(int c)int write(byte cbuf[])int write(byte cbuf[], int offset, int length)
Reading/writing files import java.io.*; public class FileCopy { public static void main(String[] args) throws IOException { File inputFile = new File("farrago.txt"); //File inputFile = new File("C:\\farrago.txt"); File outputFile = new File("outagain.txt"); FileReader in = new FileReader(inputFile); FileWriter out = new FileWriter(outputFile); int c; while ((c = in.read()) != -1) out.write(c); in.close(); out.close(); } }