ZetCode

Golang fmt.Scan function

last modified May 8, 2025

This tutorial explains how to use the fmt.Scan function in Go. We'll cover input basics with practical examples of reading user input.

The fmt.Scan function is used to read input from standard input. It scans text read from standard input and stores successive space-separated values into successive arguments. Newlines count as space.

In Go, fmt.Scan is part of the fmt package for formatted I/O. It's useful for simple command-line programs that need user interaction.

Basic fmt.Scan example

The simplest use of fmt.Scan reads a single value from input. This example demonstrates basic input scanning.
Note: Scan requires pointers to variables as arguments.

basic_scan.go
package main

import "fmt"

func main() {
    var name string
    
    fmt.Print("Enter your name: ")
    fmt.Scan(&name)
    
    fmt.Printf("Hello, %s!\n", name)
}

The program prompts for a name, reads it with fmt.Scan, then greets the user. The & operator gets the variable's address.

Scanning multiple values

fmt.Scan can read multiple values separated by whitespace. This example shows how to scan several values at once.

multiple_scan.go
package main

import "fmt"

func main() {
    var firstName, lastName string
    var age int
    
    fmt.Print("Enter first name, last name, and age: ")
    fmt.Scan(&firstName, &lastName, &age)
    
    fmt.Printf("%s %s is %d years old\n", 
        firstName, lastName, age)
}

The program reads three values in one Scan call. Input should be space-separated (e.g., "John Doe 30").

Handling scan errors

fmt.Scan returns the count of successfully scanned items. This example demonstrates error handling with the return value.

scan_errors.go
package main

import "fmt"

func main() {
    var a, b int
    
    fmt.Print("Enter two numbers: ")
    n, err := fmt.Scan(&a, &b)
    
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    
    if n != 2 {
        fmt.Println("Expected 2 values, got", n)
        return
    }
    
    fmt.Printf("Sum: %d\n", a+b)
}

The program checks both the count of scanned items and any error. This makes the input handling more robust against invalid input.

Scanning different data types

fmt.Scan can handle various data types automatically. This example shows scanning different types in one operation.

scan_types.go
package main

import "fmt"

func main() {
    var name string
    var age int
    var height float64
    var student bool
    
    fmt.Print("Enter name, age, height, student (true/false): ")
    fmt.Scan(&name, &age, &height, &student)
    
    fmt.Printf("%s: %d years, %.2f m, student: %t\n",
        name, age, height, student)
}

The program reads a string, integer, float, and boolean value. fmt.Scan automatically converts the input to the correct type.

Using fmt.Scan with slices

For reading multiple values into a slice, we can use variadic arguments. This example demonstrates scanning into a slice of integers.

scan_slice.go
package main

import "fmt"

func main() {
    numbers := make([]int, 3)
    
    fmt.Print("Enter 3 numbers: ")
    fmt.Scan(&numbers[0], &numbers[1], &numbers[2])
    
    sum := 0
    for _, num := range numbers {
        sum += num
    }
    
    fmt.Println("Sum:", sum)
}

The program reads three numbers into a slice then calculates their sum. Each slice element must be scanned individually with its address.

Scanning lines with fmt.Scan

For reading entire lines including spaces, fmt.Scan has limitations. This example shows a workaround for reading full lines.

scan_lines.go
package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    reader := bufio.NewReader(os.Stdin)
    
    fmt.Print("Enter a sentence: ")
    input, _ := reader.ReadString('\n')
    
    fmt.Print("You entered: ", input)
}

For line-based input, bufio.Reader is often better than fmt.Scan. This approach reads until the newline character.

Advanced scanning with fmt.Scanf

For formatted scanning, fmt.Scanf provides more control. This example demonstrates pattern-based input scanning.

scan_formatted.go
package main

import "fmt"

func main() {
    var day, month, year int
    
    fmt.Print("Enter date (dd-mm-yyyy): ")
    fmt.Scanf("%d-%d-%d", &day, &month, &year)
    
    fmt.Printf("Date: %02d/%02d/%04d\n", 
        day, month, year)
}

fmt.Scanf uses format specifiers to parse input. The input must match the specified format (e.g., "25-12-2023").

Source

Go fmt package documentation

This tutorial covered the fmt.Scan function in Go with practical examples of reading user input in various formats.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Golang tutorials.