Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Go  Module 2 – Basics: values, types and control flow

Formatted output with fmt: verbs and widths

Print Go values with Println, Printf and Sprintf, choose verbs such as %v, %+v, %#v, %T, %q and %x, and line up columns with width, precision and flags.

  • Beginner
  • 10 minutes
  • Examples run with Go 1.27.1 and Python 3.14.8
  • By MySmartCoPilot
Free core, Pro depth: 4 of 10 minutes free
Free: Println, Printf and Sprintf differ in spaces, newlines and destination · A verb chooses how each value is shown · Width, precision and flags line up columns. With a pass: 2 in-depth parts and 3 interview answers, about 6 minutes.

What you will learn

  • Choose between Print, Println, Printf, Sprintf and Fprintf for a piece of output
  • Choose the verb that shows a value as needed: %v, %+v, %#v, %T, %q, %x, %d or %f
  • Format columns with width, precision, padding and the - flag
  • Recognise the markers a wrong verb prints, and find the mistake with go vet
  • Write a String method that %v uses, without the recursion trap

Before you start

What you’ll learn · Before you start

What you will learn

  • Choose between Print, Println, Printf, Sprintf and Fprintf for a piece of output
  • Choose the verb that shows a value as needed: %v, %+v, %#v, %T, %q, %x, %d or %f
  • Format columns with width, precision, padding and the - flag
  • Recognise the markers a wrong verb prints, and find the mistake with go vet
  • Write a String method that %v uses, without the recursion trap

Before you start

On this page

A bill that prints Samosa 3 54.00 on one line and Filter coffee 1 40.50 on the next is hard to read; the same numbers in columns are not. Go’s fmt package writes such columns with a format string: %-14s puts a string left-aligned in 14 characters, %4d a number right-aligned in 4, and verbs like them decide how each value appears.

You will choose between Println, Printf and Sprintf, pick the verb that shows a value the way you need, and line up a table with widths and padding. The programs below ran on Go 1.27.1, and each shows what it printed.

Println, Printf and Sprintf differ in spaces, newlines and destination

The print functions come in families. Print and Println write their operands in their default format; Printf follows a format string: The first argument of Printf, Sprintf and their relatives: text in which each verb, such as %d or %s, marks where the next argument goes and how it is shown. The rest of the text is copied as it is.; the S versions return the text, and the F versions write to any destination that accepts bytes:

print_funcs.go: five ways to print Go · print_funcs.go
// print_funcs.go: where each print function puts its text, and its spaces.
package main

import (
	"fmt"
	"os"
	"strings"
)

func main() {
	fmt.Print("total", 3, 4, "\n")    // a space only between two operands that are not strings
	fmt.Println("total", 3, 4)        // a space between all operands, then a newline
	fmt.Printf("total %d+%d\n", 3, 4) // a format string; the newline is yours to write

	line := fmt.Sprintf("%d items", 7) // returns the text instead of printing it
	fmt.Println(len(line), "bytes:", line)

	var b strings.Builder
	fmt.Fprintf(&b, "order %d", 15) // writes to any io.Writer
	fmt.Fprintln(os.Stdout, b.String())

	fmt.Println("total %d", 3) // Println prints a verb as it is
}

Output

total3 4
total 3 4
total 3+4
7 bytes: 7 items
order 15
total %d 3

Recorded with Go 1.27.1 on macOS 26 arm64. To run it yourself: go run print_funcs.go

Print added a space only between 3 and 4, the two operands that are not strings, so total and 3 ran together. Println put a space between every operand and ended the line. Printf printed exactly what its format said, its newline included, and Sprintf returned a 7-byte string instead of printing it. Fprintf wrote into a strings.Builder; the same call writes to os.Stderr, a file or a network connection.

A verb in Println

fmt.Println("total %d", 3) printed total %d 3: Println does not read verbs. Use Printf whenever the text holds a verb, and remember the \n that Println would have added.

Checkpoint

Check: Print, Println, Printf, Sprintf and Fprintf

  1. Question 1 of 2 What does this print?

    Read the code, then choose one answer.

    fmt.Print("id", 7, 8, "\n")
    Show the answer: Question 1 of 2

    Answer: id7 8

    Print separates two operands only when neither is a string, which is why print_funcs.go printed total3 4.

  2. Question 2 of 2 What does fmt.Sprintf("%d items", 7) do?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: It returns the string 7 items and prints nothing

    Sprintf formats like Printf but returns the result, for building a value, a message or a key.

A verb chooses how each value is shown

In a format string, % and a letter form a verb: In a format string, a percent sign and a letter, such as %d, %s or %v, that takes the next argument and says how to show it. Flags, a width and a precision may stand between the two., and each verb takes the next argument. %v works for every type, which is why Println uses it. The others choose a view:

verbs.go: one value, several verbs Go · verbs.go
// verbs.go: one value, several verbs.
package main

import "fmt"

type Ticket struct {
	ID    int
	Route string
	Fare  float64
}

func main() {
	t := Ticket{ID: 42, Route: "Pune-Mumbai", Fare: 355.5}
	fmt.Printf("%v\n", t)
	fmt.Printf("%+v\n", t)
	fmt.Printf("%#v\n", t)
	fmt.Printf("%T\n", t)

	fmt.Printf("%d %s %q %t\n", 42, "seat", "seat 4", true)
	fmt.Printf("%x %X %o %b\n", 255, 255, 8, 5)
	fmt.Printf("%f %.2f %e %g\n", 355.5, 355.5, 355.5, 355.5)
	fmt.Printf("%c %U %q\n", '₹', '₹', '₹')
}

Output

{42 Pune-Mumbai 355.5}
{ID:42 Route:Pune-Mumbai Fare:355.5}
main.Ticket{ID:42, Route:"Pune-Mumbai", Fare:355.5}
main.Ticket
42 seat "seat 4" true
ff FF 10 101
355.500000 355.50 3.555000e+02 355.5
₹ U+20B9 '₹'

Recorded with Go 1.27.1 on macOS 26 arm64. To run it yourself: go run verbs.go

Verb Shows In the run
%v the default format {42 Pune-Mumbai 355.5}
%+v structs with field names {ID:42 Route:… Fare:355.5}
%#v Go syntax for the value main.Ticket{ID:42, …}
%T the type main.Ticket
%d %x %o %b an integer in base 10, 16, 8 or 2 42, ff, 10, 101
%f %e %g a float with a point, with an exponent, or %e for large exponents and %f otherwise 355.500000, 3.555000e+02, 355.5
%s %q a string as it is, or quoted and escaped seat, "seat 4"
%c %U a rune as a character, or its code point ₹, U+20B9

%+v is the one to reach for when you debug a struct, because it names every field, and %#v prints text you can paste into a test. A type can also choose its own text for %v with a String method.

Programmer Calculator (Bitwise) Convert numbers between decimal, hex, octal and binary to check what %x, %o and %b print.

Checkpoint

Check: Choosing a verb

  1. Question 1 of 2 Which verb printed {ID:42 Route:Pune-Mumbai Fare:355.5} for the Ticket in verbs.go?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: %+v

    %v shows values, %+v adds field names, %#v gives Go syntax, and %T the type.

  2. Question 2 of 2 What does fmt.Printf("%q\n", "seat 4") print?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: "seat 4", with the double quotes

    %q quotes and escapes, which makes spaces, tabs and invisible characters easy to see in a log line.

Width, precision and flags line up columns

Between % and the letter, a number sets the width, the least number of characters to fill, and a dot with a number sets the precision. Flags change the padding: - puts the spaces on the right, 0 pads numbers with zeros, + always shows a sign. Here the amounts stay in whole paise, hundredths of a rupee, and print through %d.%02d:

invoice.go: a bill in aligned columns Go · invoice.go
// invoice.go: columns lined up with widths, and rupees printed from paise.
package main

import "fmt"

type line struct {
	item  string
	qty   int
	paise int64 // the price of one, in paise (₹1 = 100 paise)
}

func main() {
	lines := []line{{"Masala chai", 2, 2500}, {"Samosa", 3, 1800}, {"Filter coffee", 1, 4050}}
	fmt.Printf("%-14s %4s %10s\n", "Item", "Qty", "Amount ₹")
	var total int64
	for _, l := range lines {
		amount := int64(l.qty) * l.paise
		total += amount
		fmt.Printf("%-14s %4d %7d.%02d\n", l.item, l.qty, amount/100, amount%100)
	}
	fmt.Printf("%-14s %4s %7d.%02d\n", "Total", "", total/100, total%100)
	fmt.Printf("[%6s] [%-6s] [%06d] [%+d]\n", "₹50", "₹50", 42, 42)
}

Output

Item            Qty   Amount ₹
Masala chai       2      50.00
Samosa            3      54.00
Filter coffee     1      40.50
Total                   144.50
[   ₹50] [₹50   ] [000042] [+42]

Recorded with Go 1.27.1 on macOS 26 arm64. To run it yourself: go run invoice.go

Step through how Printf builds the Samosa line:

Interactive · stage by stage How Printf builds one line of the invoice Step through the Samosa line of invoice.go; each verb takes the next argument, and the text between the verbs is copied as it is.
How Printf builds one line of the invoice, step 5 of 5. Showing %-14s takes "Samosa" (Samosa and 8 spaces), %4d takes 3 (3 spaces, then 3), %7d takes 54 (5 spaces, then 54), %02d takes 0 (00), \n ends the line. In focus: \n ends the line.%-14s takes "Samosa"Samosa and 8 spaces%4d takes 33 spaces, then 3%7d takes 545 spaces, then 54%02d takes 000\n ends the linePrintf adds no newline

The drawing shows the whole scene; its 5 steps are listed below.

Every step as text
  1. The first verb. %-14s takes the first argument, the string Samosa. Its 6 characters are padded with 8 spaces to a width of 14, and the - flag puts the spaces on the right, so the text starts at the left edge.
  2. A space, then a number. The space after the verb is plain text and is copied. %4d takes the next argument, 3, and pads it on the left to 4 characters, because numbers are right-aligned by default.
  3. The rupees. Another copied space, then %7d takes 54, the whole rupees of 5400 paise. Five spaces of padding bring it to 7 characters, under the Amount header.
  4. The paise. The dot is copied as it is. %02d takes 0, the paise left over, and the 0 flag pads with zeros instead of spaces, so the line shows 54.00, never 54.0.
  5. The end of the line. \n is the last plain text of the format. Printf writes only what the format says, so without it the next line would start right after 54.00.

Every amount ends at the same column because %7d.%02d makes each amount here 10 characters wide, as wide as the header’s %10s. Width counts characters, not bytes: "₹50" is 5 bytes, yet %6s padded it with 3 spaces, which differs from C’s printf. For a float, %.2f keeps two digits after the point; for a string, precision cuts it.

Key idea

The width is the least room a value takes, and the precision how much of it is shown: digits for a float, characters for a string.

Checkpoint

Check: Width, precision and flags

  1. Question 1 of 2 What does fmt.Printf("[%-6s|]\n", "ab") print?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: [ab |]

    A width is the least number of characters a value takes; - puts the padding after the value.

  2. Question 2 of 2 What does %05d print for 42?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: 00042

    %02d in invoice.go used the same flag to print 0 paise as 00.

Wrong verbs, missing arguments and go vet, reproduced Pro: opens with a Pro, Premium or Ultimate pass

fmt finds a mismatch between a verb and its argument only while the program runs, and then prints a marker into the output instead of stopping. This part reproduces six of these markers, then lets go vet find the same mistakes before anything runs.

In this part:

  • What Printf prints when a verb and its argument disagree, six markers reproduced
  • Text from data used as a format string breaks on its first percent sign
  • Your own Printf-like functions print the same markers
  • go vet reports these before the program runs, wrappers included

4 runnable examples (Go, Python) · about 5 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

Go syntax, argument indexes and String methods, measured Pro: opens with a Pro, Premium or Ultimate pass

%v, %+v and %#v follow pointers into structs, slices and maps, an argument index reuses one value several times, and a String method replaces what %v prints. This part measures each, with the pointer receiver that keeps a String method from being used and the recursion vet warns about.

In this part:

  • Pointers, slices, maps and nil values under %v, %+v and %#v
  • Argument indexes and widths read from arguments
  • A String method changes what %v prints, if the value has the method
  • String methods inside slices, maps and struct fields

1 diagram · 6 runnable examples (Go, Python) · about 6 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

Practise

Practice on the print functions, the verbs and the widths opens with whichever of the three your answers so far leave weakest, and every choice you pick is explained on the spot:

Practice that adapts to you

Practise this lesson

8 questions about 5 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.

  1. Question 1 of 8 Which print function ends its output with a newline by itself?

    Choose one answer.

    Show the answer: Question 1 of 8

    Answer: Println

    Println, Sprintln and Fprintln add the newline; the f and plain forms never do.

  2. Question 2 of 8 A report function must write to standard output in the program and into a buffer in its test. Which design lets the same code do both?

    Choose one answer.

    Show the answer: Question 2 of 8

    Answer: Take an io.Writer parameter and write with fmt.Fprintf(w, …)

    The F functions write to an io.Writer, which is how print_funcs.go wrote into a strings.Builder.

  3. Question 3 of 8 Which verb printed main.Ticket in verbs.go?

    Choose one answer.

    Show the answer: Question 3 of 8

    Answer: %T

    %T helps when you debug a value whose type you are not sure of, such as one held in an interface.

  4. Question 4 of 8 What does fmt.Printf("%x %o\n", 255, 8) print?

    Choose one answer.

    Show the answer: Question 4 of 8

    Answer: ff 10

    %b, %o, %x and %X print an integer in base 2, 8 and 16, as verbs.go printed ff FF 10 101.

  5. Question 5 of 8 You want to copy a value from a log line straight into a Go test as the expected value. Which verb should the log use?

    Choose one answer.

    Show the answer: Question 5 of 8

    Answer: %#v

    %#v is the Go-syntax view of a value: main.Ticket{ID:42, Route:"Pune-Mumbai", Fare:355.5}.

  6. Question 6 of 8 An amount of 5405 paise is printed with %d.%d and the values 54 and 5. What appears, and what should the format be?

    Choose one answer.

    Show the answer: Question 6 of 8

    Answer: 54.5, and the format should be %d.%02d

    invoice.go prints rupees and paise from whole paise with %7d.%02d, so every amount has two paise digits.

  7. Question 7 of 8 What does fmt.Printf("[%6.2f]\n", 3.14159) print?

    Choose one answer.

    Show the answer: Question 7 of 8

    Answer: [ 3.14]

    For a float, %w.pf gives p digits after the point in a field at least w characters wide.

  8. Question 8 of 8 How many spaces does fmt.Printf("[%5s]", "₹9") put before ₹9?

    Type a number.

    A hint

    Width counts characters, not bytes, and ₹ is one character of three bytes.

    Show the answer: Question 8 of 8

    Answer: 3 spaces

    ₹9 is 2 characters, so width 5 adds 3 spaces, although the string is 4 bytes: fmt measures width in runes, unlike C's printf.

Interview questions

Warm-up (fresher): What is the difference between %v, %+v and %#v?

All three print a value. %v uses the default format, such as {42 Pune-Mumbai 355.5} for a struct. %+v adds the field names of structs, and %#v prints the value in Go syntax, with its type, which you could paste into code.

Three longer questions of the module bank build on this lesson:

  1. Fresher to mid

    A service writes request details with log.Printf(msg), where msg is built from what the client sent. Some log lines contain %!d(MISSING) or %!s(MISSING). What causes it, how serious is it, and how do you fix it and keep it fixed?

    Model answer, Pro. Model answers open with any pass; prices are in the notice on this page. First step and follow-ups

  2. Fresher to mid

    Print a table of item names, quantities and amounts kept in paise so that the columns line up, for names of any length. Which verbs and widths do you use, and what goes wrong when a name is longer than its column?

    Model answer, Pro. First step and follow-ups

  3. Fresher to mid

    A type Paise int64 has func (p *Paise) String() string, which writes 35550 paise as rupees and paise. fmt.Println(&p) uses it, but fmt.Println(p) and a printed []Paise show bare numbers. Explain why, fix it, and say how you keep such a method from breaking.

    Model answer, Pro. First step and follow-ups

Key takeaways

  • Print adds spaces only between non-strings, Println always adds spaces and a newline, Printf follows its format string, Sprintf returns the text and Fprintf writes it to any writer.
  • A verb takes the next argument: %v shows any value, %+v adds field names, %#v gives Go syntax and %T the type.
  • A width is the least room a value takes, - aligns it left, 0 pads numbers with zeros, and precision sets the digits of a float or cuts a string.

Terms in this lesson

format string
The first argument of Printf, Sprintf and their relatives: text in which each verb, such as %d or %s, marks where the next argument goes and how it is shown. The rest of the text is copied as it is.
verb
In a format string, a percent sign and a letter, such as %d, %s or %v, that takes the next argument and says how to show it. Flags, a width and a precision may stand between the two.

References

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.