ZetCode

Golang fmt.Scanf function

last modified May 8, 2025

This tutorial explains how to use the fmt.Scanf function in Go. We'll cover input parsing basics with practical examples of formatted input.

The fmt.Scanf function scans text from standard input, storing successive space-separated values into arguments according to a format string. It returns the number of items successfully scanned.

In Go, fmt.Scanf is similar to C's scanf but with type safety. It's useful for parsing structured input data with known formats. The function stops scanning at newlines unless specified otherwise in the format.

Basic fmt.Scanf example

The simplest use of fmt.Scanf reads a single value from input. This example demonstrates basic integer input parsing.
Note: Always check the return value for successful scanning.

basic_scanf.go
package main

import "fmt"

func main() {
    var age int
    
    fmt.Print("Enter your age: ")
    n, err := fmt.Scanf("%d", &age)
    
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    
    fmt.Printf("Scanned %d value(s): Age = %d\n", n, age)
}

The program reads an integer from standard input. The %d verb matches decimal integers. We store the result in the age variable.

Reading multiple values

fmt.Scanf can parse multiple values in one call. This example shows how to read different data types simultaneously.

multiple_values.go
package main

import "fmt"

func main() {
    var name string
    var age int
    var height float64
    
    fmt.Print("Enter name, age, and height: ")
    n, err := fmt.Scanf("%s %d %f", &name, &age, &height)
    
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    
    fmt.Printf("Scanned %d values:\n", n)
    fmt.Printf("Name: %s\nAge: %d\nHeight: %.2f\n", 
        name, age, height)
}

The format string "%s %d %f" matches a string, integer, and float. Values must be space-separated in the input. The order must match the variables.

Handling string input with spaces

By default, %s stops at whitespace. This example shows how to read entire lines or strings containing spaces.

string_with_spaces.go
package main

import "fmt"

func main() {
    var firstName, lastName string
    
    fmt.Print("Enter your full name: ")
    n, err := fmt.Scanf("%s %s", &firstName, &lastName)
    
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    
    fmt.Printf("Scanned %d names:\n", n)
    fmt.Printf("First: %s\nLast: %s\n", firstName, lastName)
}

This reads two separate words into different variables. For full names with middle names, consider using bufio.Scanner instead.

Custom delimiters with fmt.Scanf

fmt.Scanf can parse input with custom delimiters using the format string. This example demonstrates comma-separated value parsing.

custom_delimiters.go
package main

import "fmt"

func main() {
    var x, y int
    
    fmt.Print("Enter coordinates (x,y): ")
    n, err := fmt.Scanf("%d,%d", &x, &y)
    
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    
    fmt.Printf("Scanned %d values: (%d, %d)\n", n, x, y)
}

The format string "%d,%d" expects two integers separated by a comma. The input must exactly match this format for successful parsing.

Reading until newline

To read until newline, include \n in the format string. This example shows how to consume the entire input line.

read_until_newline.go
package main

import "fmt"

func main() {
    var message string
    
    fmt.Print("Enter a message: ")
    n, err := fmt.Scanf("%[^\n]\n", &message)
    
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    
    fmt.Printf("Scanned %d values:\nMessage: %q\n", 
        n, message)
}

The format %[^\n]\n reads all characters until newline, then consumes the newline. This allows reading strings with spaces.

Validating input with fmt.Scanf

fmt.Scanf can validate input format during scanning. This example demonstrates date format validation.

input_validation.go
package main

import "fmt"

func main() {
    var day, month, year int
    
    fmt.Print("Enter date (dd-mm-yyyy): ")
    n, err := fmt.Scanf("%d-%d-%d", &day, &month, &year)
    
    if err != nil || n != 3 {
        fmt.Println("Invalid date format")
        return
    }
    
    fmt.Printf("Date: %02d/%02d/%04d\n", day, month, year)
}

The format "%d-%d-%d" ensures input matches the dd-mm-yyyy pattern. The return value checks if all three values were successfully parsed.

Advanced format verbs

fmt.Scanf supports various format verbs for different data types. This example shows hexadecimal and boolean input parsing.

format_verbs.go
package main

import "fmt"

func main() {
    var hexValue int
    var flag bool
    var str string
    
    fmt.Print("Enter hex, bool, string (ex: 0x1A true text): ")
    n, err := fmt.Scanf("%x %t %s", &hexValue, &flag, &str)
    
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    
    fmt.Printf("Scanned %d values:\n", n)
    fmt.Printf("Hex: %#x\nBool: %t\nString: %q\n", 
        hexValue, flag, str)
}

The %x verb parses hexadecimal numbers, %t parses booleans, and %s parses strings. Each verb matches its specific type in the input.

Source

Go fmt package documentation

This tutorial covered the fmt.Scanf function in Go with practical examples of formatted input parsing and validation.

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.