Kotlin I/O con la Console
Output su schermo
Kotlin offre semplicemente due funzione: print() e println() . Esse scrivono sullo standard output il messaggio passato come argomento. Queste funzioni le abbiamo già viste nel corso delle prime 4 lezioni. C'è da ricordare che println() stampa la string seguita dal delimitatore di fine linea \n e/o \r.
Per scrivere sullo standard error (lo stream speciale dedicato agli errori) basta usare i metodi System.err.println() e System.err.print().
Input da tastiera
Kotlin offre semplicemente una funzione: readline(), il quale legge e restituisce una linea (delimitata da \n e/o \r) dallo stream di input e la riporta in una stringa. Il valore può ritornare null in determinate situazioni. Per leggere un numero intero, un numero in virgola mobile, una stringa o qualsiasi altro tipo di dato, è necessario eseguire una conversione di tipo, dobbiamo prestare attenzione che stiamo leggendo LINEE e non parole (come avviene in C/C++ o Java con la classe Scanner), in maniera del tutto analoga al C#.
Per fortuna la classe String del Kotlin contiene dei bellissimi metodi, tra cui:
toInt()
toIntOrNull() (versione che non genera eccezioni del toInt())
toBoolean()
toByte() & toByteOrNull()
toDouble() & toDobuleOrNull()
toFloat() & toFloatOrNull()
toLong() & toLongOrNull()
split()
Tutti questi metodi ci permettono di evitare di usare una classe che parsa il testo come in Java. Detto ciò possiamo procedere in più modi:
- Trasformiamo la stringa in una lista di interi:
fun readInts(separator: Char = ' ') = readLine()!!.split(separator).map(String::toInt)
- N.B. L'operatore !! serve per generare una NullPointerException, verrà approfondito in seguito, anche la funzione map() verrà vista in un secondo momento.
- Leggiamo il primo intero, tramite il metodo della classe Array first():
fun readInt(separator: Char = ' ') = readLine()!!.split(separator).map(String::toInt).first()
- Leggiamo l'ennesimo intero tramite la notazione delle parentesi quadre ([]), ricordiamo che l'indice parte da 0:
fun readInt(index: Int, separator: Char = ' ') = readLine()!!.split(separator).map(String::toInt)[index]
- Però ci conviene salvare la stringa in una variabile, in quanto altrimenti la perderemmo, e poi da quella variabile leggere l'ennesimo intero:
fun main(args: Array<String>) {
val line = readLine()
val primoNumero = readInt(line!!,0)
val secondoNumero = readDouble(line!!,1)
val terzoNumero = readInt(line!!,2)
}
Ed ecco un esempio di utilizzo della funzione readInts() dello Snippet 4.1 combinata ad un for:
fun main(args: Array<String>) {
val ints = readInts()
for(int in ints) {
println(int)
}
}