Input e Output in Go
In Go, le operazioni di input e output sono gestite principalmente dal pacchetto fmt per la formattazione e la stampa, e dal pacchetto bufio per la lettura avanzata dell’input. Questi strumenti coprono la maggior parte delle esigenze di I/O di un programma Go.
Il Pacchetto fmt: Output
fmt.Print
Stampa i valori senza andare a capo:
package main
import "fmt"
func main() {
fmt.Print("Ciao")
fmt.Print(" mondo")
// Output: Ciao mondo
}
fmt.Println
Stampa i valori e aggiunge un ritorno a capo:
func main() {
fmt.Println("Ciao, mondo!")
fmt.Println("Benvenuto", "in", "Go")
// Output:
// Ciao, mondo!
// Benvenuto in Go
}
Println aggiunge automaticamente uno spazio tra gli argomenti.
fmt.Printf
Stampa con formattazione avanzata usando i verbi di formato:
func main() {
nome := "Marco"
eta := 30
altezza := 1.78
fmt.Printf("Nome: %s\n", nome)
fmt.Printf("Eta: %d anni\n", eta)
fmt.Printf("Altezza: %.2f m\n", altezza)
}
Verbi di Formattazione
I verbi di formato sono il cuore di Printf. Ecco i piu importanti:
Verbi Generali
valore := 42
testo := "ciao"
lista := []int{1, 2, 3}
fmt.Printf("%v\n", valore) // 42 (formato default)
fmt.Printf("%v\n", lista) // [1 2 3]
fmt.Printf("%+v\n", struct{ A int }{A: 1}) // {A:1} (con nomi dei campi)
fmt.Printf("%#v\n", lista) // []int{1, 2, 3} (sintassi Go)
fmt.Printf("%T\n", valore) // int (tipo del valore)
Verbi per Numeri
n := 42
fmt.Printf("%d\n", n) // 42 (decimale)
fmt.Printf("%b\n", n) // 101010 (binario)
fmt.Printf("%o\n", n) // 52 (ottale)
fmt.Printf("%x\n", n) // 2a (esadecimale minuscolo)
fmt.Printf("%X\n", n) // 2A (esadecimale maiuscolo)
fmt.Printf("%05d\n", n) // 00042 (padding con zeri)
Verbi per Float
f := 3.14159
fmt.Printf("%f\n", f) // 3.141590 (formato standard)
fmt.Printf("%.2f\n", f) // 3.14 (2 decimali)
fmt.Printf("%e\n", f) // 3.141590e+00 (notazione scientifica)
fmt.Printf("%g\n", f) // 3.14159 (formato compatto)
fmt.Printf("%10.3f\n", f) // 3.142 (larghezza 10, 3 decimali)
Verbi per Stringhe
s := "Go lang"
fmt.Printf("%s\n", s) // Go lang
fmt.Printf("%q\n", s) // "Go lang" (con virgolette)
fmt.Printf("%10s\n", s) // Go lang (allineamento a destra)
fmt.Printf("%-10s|\n", s) // Go lang | (allineamento a sinistra)
Verbo per Puntatori
x := 42
p := &x
fmt.Printf("%p\n", p) // 0xc0000b6010 (indirizzo di memoria)
Formattare Senza Stampare
fmt.Sprintf restituisce la stringa formattata senza stamparla:
messaggio := fmt.Sprintf("Ciao %s, hai %d anni", "Marco", 30)
fmt.Println(messaggio) // Ciao Marco, hai 30 anni
fmt.Fprintf scrive su un qualsiasi io.Writer:
fmt.Fprintf(os.Stderr, "Errore: %s\n", "file non trovato")
Il Pacchetto fmt: Input
fmt.Scan
Legge valori separati da spazi dallo standard input:
package main
import "fmt"
func main() {
var nome string
var eta int
fmt.Print("Inserisci nome e eta: ")
fmt.Scan(&nome, &eta)
fmt.Printf("Ciao %s, hai %d anni\n", nome, eta)
}
fmt.Scanf
Legge input con un formato specifico:
func main() {
var giorno, mese, anno int
fmt.Print("Inserisci data (gg/mm/aaaa): ")
fmt.Scanf("%d/%d/%d", &giorno, &mese, &anno)
fmt.Printf("Data: %02d/%02d/%04d\n", giorno, mese, anno)
}
fmt.Scanln
Legge una riga fino al ritorno a capo:
func main() {
var a, b int
fmt.Print("Inserisci due numeri: ")
fmt.Scanln(&a, &b)
fmt.Printf("Somma: %d\n", a+b)
}
La differenza con Scan e che Scanln si ferma al ritorno a capo.
bufio.Scanner per Lettura Avanzata
bufio.Scanner e lo strumento ideale per leggere input riga per riga:
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
fmt.Print("Come ti chiami? ")
scanner.Scan()
nome := scanner.Text()
fmt.Print("Quanti anni hai? ")
scanner.Scan()
etaStr := scanner.Text()
fmt.Printf("Ciao %s! Hai scritto: %s\n", nome, etaStr)
}
Leggere Piu Righe
func main() {
scanner := bufio.NewScanner(os.Stdin)
fmt.Println("Inserisci righe di testo (riga vuota per terminare):")
var righe []string
for scanner.Scan() {
riga := scanner.Text()
if riga == "" {
break
}
righe = append(righe, riga)
}
fmt.Printf("Hai inserito %d righe\n", len(righe))
for i, r := range righe {
fmt.Printf("Riga %d: %s\n", i+1, r)
}
}
os.Stdin e os.Stdout
os.Stdin e os.Stdout sono i flussi standard di input e output:
package main
import (
"io"
"os"
)
func main() {
// Scrivere direttamente su stdout
os.Stdout.WriteString("Scritto direttamente su stdout\n")
// Copiare stdin su stdout (echo)
io.Copy(os.Stdout, os.Stdin)
}
Conclusione
Go offre strumenti completi per l’input e l’output. Il pacchetto fmt con i suoi verbi di formattazione copre la maggior parte delle esigenze di output, mentre bufio.Scanner e la scelta migliore per leggere input dell’utente in modo robusto. Conoscere i verbi di formattazione e le differenze tra Scan, Scanf e Scanln permette di gestire efficacemente qualsiasi scenario di I/O.