fmt.Scan în Go

Citește valori de la tastatură (intrarea standard) în variabile; Scanln se oprește la capăt de rând, Scanf folosește un format.

Sintaxă
func Scan(a ...any) (n int, err error)
func Scanln(a ...any) (n int, err error)
func Scanf(format string, a ...any) (n int, err error)

Ce face fmt.Scan

fmt.Scan citește cuvinte separate prin spații (sau rânduri noi) de la tastatură și le pune în variabilele primite. Trebuie să dai adresele variabilelor, cu &: fmt.Scan(&nume, &varsta). Textul este convertit automat la tipul variabilei (int, float64, string).

fmt.Scanln este la fel, dar se oprește la capătul rândului: dacă rândul are mai puține valori decât variabile, returnează eroare. fmt.Scanf citește după un format cu verbe, ca Printf: fmt.Scanf("%d-%d", &a, &b) citește 3-5.

Toate returnează câte valori au citit și o eroare (de exemplu când textul nu e număr sau intrarea s-a terminat). Pentru a citi un rând întreg cu spații (un nume complet, o propoziție), folosește bufio.Scanner sau bufio.Reader.ReadString: Scan se oprește la primul spațiu.

Parametri

Parametru Descriere
a ...any Pointeri la variabilele care primesc valorile: &x.
format Doar la Scanf: șablonul intrării, cu verbe %d, %s, %f etc.

Ce returnează

Numărul de valori citite cu succes și eroarea (nil dacă totul a mers bine; io.EOF la sfârșitul intrării).

Exemple

Exemplul 1: Citirea numelui și a vârstei

package main

import "fmt"

func main() {
	var nume string
	var varsta int
	fmt.Print("Nume și vârstă: ")
	n, err := fmt.Scan(&nume, &varsta)
	fmt.Println()
	fmt.Println("valori citite:", n, "eroare:", err)
	fmt.Printf("%s va avea %d ani la anul.\n", nume, varsta+1)
}

Ce scrie utilizatorul (intrare)

Ana 20

Rezultat

Nume și vârstă: 
valori citite: 2 eroare: <nil>
Ana va avea 21 ani la anul.

Exemplul 2: Suma numerelor până la sfârșitul intrării

Scan trece peste rândurile noi. Bucla se oprește când Scan returnează eroare (aici EOF, sfârșitul intrării).

package main

import "fmt"

func main() {
	suma, cate := 0, 0
	for {
		var x int
		if _, err := fmt.Scan(&x); err != nil {
			fmt.Println("oprire:", err)
			break
		}
		suma += x
		cate++
	}
	fmt.Printf("%d numere, suma %d\n", cate, suma)
}

Ce scrie utilizatorul (intrare)

10 20
30
5

Rezultat

oprire: EOF
4 numere, suma 65

Exemplul 3: Scanf cu format și Scanln pe rând

Scanf citește o dată în formatul zi.lună.an. Scanln vrea două valori pe al doilea rând, dar găsește doar una, deci returnează eroare.

package main

import "fmt"

func main() {
	var zi, luna, an int
	n, err := fmt.Scanf("%d.%d.%d\n", &zi, &luna, &an)
	fmt.Println("Scanf:", n, err, "->", zi, luna, an)

	var oras string
	var cod int
	n, err = fmt.Scanln(&oras, &cod)
	fmt.Println("Scanln:", n, err, "->", oras)
}

Ce scrie utilizatorul (intrare)

01.12.2026
Iași

Rezultat

Scanf: 3 <nil> -> 1 12 2026
Scanln: 1 unexpected newline -> Iași

Greșeli frecvente

  • Uiți &: fmt.Scan(nume). Scan nu poate schimba variabila și returnează eroarea expected pointer; go vet te avertizează.
  • Vrei să citești „Ana Maria Popescu” cu un singur Scan(&nume). Primești doar „Ana”, iar restul rămâne pentru următoarea citire. Pentru rânduri întregi folosește bufio.Scanner.
  • Nu verifici eroarea. Dacă utilizatorul scrie „zece” în loc de 10, variabila rămâne 0 și programul continuă cu o valoare greșită.

Comenzi înrudite

  • fmt.Sscanf: Citește valori dintr-un text (string) în variabile, ca Scan, Scanf și Scanln, dar fără tastatură.
  • fmt.Fscan: Citește valori dintr-un io.Reader (fișier, buffer, os.Stdin) în variabile, ca Scan, Scanf și Scanln.
  • strconv.Atoi: Atoi transformă un text în număr întreg (int) și returnează eroare dacă nu se poate; Itoa face invers.