fmt.Printf în Go

Afișează text formatat cu %d, %s, %.2f etc.; Sprintf returnează textul, Fprintf îl scrie într-un fișier sau alt Writer.

Sintaxă
func Printf(format string, a ...any) (n int, err error)
func Sprintf(format string, a ...any) string
func Fprintf(w io.Writer, format string, a ...any) (n int, err error)

Ce face fmt.Printf

fmt.Printf primește un text-șablon (formatul) în care fiecare verb care începe cu % este înlocuit, în ordine, cu următoarea valoare. Cele mai folosite verbe: %v (orice valoare, formatul implicit), %d (întreg), %s (text), %q (text între ghilimele), %f sau %.2f (număr cu virgulă, cu 2 zecimale), %t (bool), %T (tipul valorii), %x (hexazecimal), %c (caracter), %% (semnul procent).

Între % și literă poți pune lățimea și alinierea: %5d ocupă 5 poziții, aliniat la dreapta; %-10s ocupă 10 poziții, aliniat la stânga; %05d completează cu zerouri. Lățimea se măsoară în caractere, nu în octeți, deci textele cu diacritice se aliniază corect. Pentru structuri, %+v afișează și numele câmpurilor, iar %#v afișează valoarea ca în codul Go.

Printf nu trece singur la rând nou: pune \n la final. fmt.Sprintf are aceleași reguli, dar nu afișează nimic: returnează textul, ca să îl pui într-o variabilă. fmt.Fprintf scrie textul într-un io.Writer: un fișier, os.Stdout, un strings.Builder, răspunsul unui server web.

Parametri

Parametru Descriere
format Textul-șablon cu verbe %…. Trebuie să fie o constantă text; go vet verifică dacă verbele se potrivesc cu valorile.
a ...any Valorile care înlocuiesc verbele, în ordine.
w io.Writer Doar la Fprintf: unde se scrie (fișier, os.Stdout, strings.Builder etc.).

Ce returnează

Printf și Fprintf: numărul de octeți scriși și eroarea de scriere. Sprintf: textul formatat (string).

Exemple

Exemplul 1: Verbele de bază

package main

import "fmt"

type Produs struct {
	Nume string
	Pret float64
}

func main() {
	nume := "Ana"
	varsta := 21
	media := 9.456
	fmt.Printf("%s are %d de ani.\n", nume, varsta)
	fmt.Printf("Media: %.2f (rotunjit), %f (implicit)\n", media, media)
	fmt.Printf("Text între ghilimele: %q\n", "Iași")
	fmt.Printf("Tipuri: %T %T %T\n", nume, varsta, media)
	fmt.Printf("255 în hexa: %x, ca bool: %t, caracter: %c\n", 255, true, 'ș')
	fmt.Printf("Reducere: 20%%\n")

	p := Produs{"pâine", 4.5}
	fmt.Printf("%v\n%+v\n%#v\n", p, p, p)
}

Rezultat

Ana are 21 de ani.
Media: 9.46 (rotunjit), 9.456000 (implicit)
Text între ghilimele: "Iași"
Tipuri: string int float64
255 în hexa: ff, ca bool: true, caracter: ș
Reducere: 20%
{pâine 4.5}
{Nume:pâine Pret:4.5}
main.Produs{Nume:"pâine", Pret:4.5}

Exemplul 2: Tabel aliniat cu lățime fixă

%-10s aliniază numele la stânga pe 10 caractere, %6.2f aliniază prețul la dreapta pe 6 caractere cu 2 zecimale. Diacriticele nu strică alinierea.

package main

import "fmt"

func main() {
	produse := []string{"pâine", "brânză", "ouă", "cafea"}
	preturi := []float64{4.5, 32.9, 1.2, 18}
	fmt.Printf("%-10s %6s\n", "Produs", "Preț")
	for i, p := range produse {
		fmt.Printf("%-10s %6.2f lei\n", p, preturi[i])
	}
	fmt.Printf("Factura nr. %05d\n", 42)
}

Rezultat

Produs       Preț
pâine        4.50 lei
brânză      32.90 lei
ouă          1.20 lei
cafea       18.00 lei
Factura nr. 00042

Exemplul 3: Sprintf pentru un text păstrat și Fprintf într-un fișier

Sprintf construiește textul fără să-l afișeze. Fprintf scrie în fișierul creat cu os.Create; apoi citim fișierul ca să vedem conținutul.

package main

import (
	"fmt"
	"os"
)

func main() {
	mesaj := fmt.Sprintf("Comanda #%d: %d bucăți x %.2f lei", 7, 3, 12.5)
	fmt.Println(mesaj)
	fmt.Println("Lungimea mesajului în octeți:", len(mesaj))

	f, err := os.Create("raport.txt")
	if err != nil {
		fmt.Println("eroare:", err)
		return
	}
	fmt.Fprintf(f, "Elev: %s\nNota: %d\n", "Ion", 9)
	f.Close()

	continut, _ := os.ReadFile("raport.txt")
	fmt.Print(string(continut))
	fmt.Fprintf(os.Stdout, "Gata, %s!\n", "Maria")
}

Rezultat

Comanda #7: 3 bucăți x 12.50 lei
Lungimea mesajului în octeți: 34
Elev: Ion
Nota: 9
Gata, Maria!

Greșeli frecvente

  • Uiți \n la final și rezultatele următoare apar pe același rând.
  • Pui mai puține sau mai multe valori decât verbe, ori un verb nepotrivit (%d pentru un text). Programul compilează, dar afișează %!d(string=Ana) sau %!(EXTRA ...). Rulează go vet: prinde aceste greșeli.
  • Folosești %d pentru un float64. Pentru numere cu virgulă folosește %f, %.2f sau %g.
  • Dai un text venit de la utilizator ca format: fmt.Printf(text). Dacă textul conține %, rezultatul se strică. Scrie fmt.Print(text) sau fmt.Printf("%s", text).

Comenzi înrudite

  • fmt.Println: Afișează valorile pe ecran: Println pune spații între ele și trece la rând nou, Print nu.
  • fmt.Sprint: Transformă valorile în text și îl returnează, fără să afișeze nimic; Sprintln adaugă spații și rând nou.
  • fmt.Fprintln: Scrie valorile într-un io.Writer (fișier, buffer, răspuns HTTP) cu regulile lui Println, respectiv Print.
  • fmt.Errorf: Creează o eroare cu mesaj formatat; cu %w împachetează o eroare existentă, care poate fi găsită apoi cu errors.Is.
  • fmt.Appendf: Formatează valorile ca Sprint, Sprintf sau Sprintln, dar adaugă rezultatul la un []byte existent.
  • strconv.FormatFloat: Transformă un număr cu zecimale în text, cu formatul (‘f’, ‘e’, ‘g’) și numărul de zecimale dorite.