ZetCode

Golang fmt.Fscanln function

last modified May 8, 2025

This tutorial explains how to use the fmt.Fscanln function in Go. We'll cover input scanning basics with practical examples of reading formatted input from various sources.

The fmt.Fscanln function reads from an io.Reader and scans space- separated values into successive arguments. It stops scanning at a newline and after the final item, there must be a newline or EOF.

In Go, fmt.Fscanln is similar to fmt.Scanln but works with any io.Reader. It's useful for reading structured input from files, network connections, or custom readers.

Basic Fscanln usage

The simplest use of fmt.Fscanln reads values from a string reader. This example demonstrates basic input scanning.
Note: Values must be space-separated and end with a newline.

basic_fscanln.go
package main

import (
    "fmt"
    "strings"
)

func main() {
    input := "John 25 true\n"
    reader := strings.NewReader(input)
    
    var name string
    var age int
    var active bool
    
    n, err := fmt.Fscanln(reader, &name, &age, &active)
    
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    
    fmt.Printf("Read %d values: %s, %d, %t\n", n, name, age, active)
}

The code reads three different types from a string. The function returns the count of successfully scanned items and any error encountered.

Reading from standard input

fmt.Fscanln can read directly from standard input using os.Stdin. This example shows interactive input scanning.

stdin_fscanln.go
package main

import (
    "fmt"
    "os"
)

func main() {
    fmt.Println("Enter your name and age (separated by space):")
    
    var name string
    var age int
    
    n, err := fmt.Fscanln(os.Stdin, &name, &age)
    
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    
    fmt.Printf("Hello %s! You are %d years old.\n", name, age)
    fmt.Printf("Successfully read %d values.\n", n)
}

The program waits for user input and reads two values. The newline after input is required for Fscanln to complete successfully.

Reading from a file

fmt.Fscanln is commonly used to read structured data from files. This example demonstrates file input scanning.

file_fscanln.go
package main

import (
    "fmt"
    "os"
)

func main() {
    file, err := os.Open("data.txt")
    if err != nil {
        fmt.Println("Error opening file:", err)
        return
    }
    defer file.Close()
    
    var product string
    var price float64
    var quantity int
    
    _, err = fmt.Fscanln(file, &product, &price, &quantity)
    if err != nil {
        fmt.Println("Error reading file:", err)
        return
    }
    
    fmt.Printf("Product: %s\nPrice: $%.2f\nQuantity: %d\n", 
        product, price, quantity)
}

The code reads a single line from a file containing product data. Remember to handle file opening errors and close the file when done.

Handling multiple lines

To read multiple lines, use fmt.Fscanln in a loop. This example shows how to process structured data line by line.

multiline_fscanln.go
package main

import (
    "bufio"
    "fmt"
    "strings"
)

func main() {
    data := `Alice 25
Bob 30
Charlie 35`
    
    scanner := bufio.NewScanner(strings.NewReader(data))
    
    for scanner.Scan() {
        line := scanner.Text()
        reader := strings.NewReader(line)
        
        var name string
        var age int
        
        _, err := fmt.Fscanln(reader, &name, &age)
        if err != nil {
            fmt.Println("Error:", err)
            continue
        }
        
        fmt.Printf("%s is %d years old\n", name, age)
    }
}

The code combines bufio.Scanner for line reading with Fscanln for parsing each line. This pattern is efficient for structured text processing.

Reading different data types

fmt.Fscanln can handle various Go types automatically. This example demonstrates reading mixed data types from input.

mixed_types.go
package main

import (
    "fmt"
    "strings"
)

func main() {
    input := "Go 1.21 true 42\n"
    reader := strings.NewReader(input)
    
    var lang string
    var version float64
    var compiled bool
    var year int
    
    n, err := fmt.Fscanln(reader, &lang, &version, &compiled, &year)
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    
    fmt.Printf("Read %d values:\n", n)
    fmt.Println("Language:", lang)
    fmt.Println("Version:", version)
    fmt.Println("Compiled:", compiled)
    fmt.Println("Year:", year)
}

The function automatically converts input strings to the target variable types. Conversion errors are returned if the input doesn't match the expected type.

Error handling

Proper error handling is crucial when using fmt.Fscanln. This example shows comprehensive error checking.

error_handling.go
package main

import (
    "fmt"
    "strings"
)

func main() {
    testCases := []string{
        "100 200\n",
        "100\n",
        "100 abc\n",
        "100 200 300\n",
    }
    
    for _, input := range testCases {
        reader := strings.NewReader(input)
        var a, b int
        
        n, err := fmt.Fscanln(reader, &a, &b)
        fmt.Printf("Input: %q\n", input)
        
        if err != nil {
            fmt.Println("  Error:", err)
        } else {
            fmt.Printf("  Read %d values: %d, %d\n", n, a, b)
        }
    }
}

The code tests various input scenarios and shows how Fscanln behaves with different inputs. Always check both the return count and error.

Reading into a slice

While fmt.Fscanln requires fixed arguments, we can read into a slice with some additional code. This example demonstrates the technique.

slice_reading.go
package main

import (
    "fmt"
    "strings"
)

func main() {
    input := "5 10 15 20 25\n"
    reader := strings.NewReader(input)
    
    var nums []int
    for {
        var num int
        n, err := fmt.Fscanln(reader, &num)
        
        if n == 0 || err != nil {
            break
        }
        
        nums = append(nums, num)
    }
    
    fmt.Println("Read numbers:", nums)
    fmt.Println("Sum:", sum(nums))
}

func sum(nums []int) int {
    total := 0
    for _, n := range nums {
        total += n
    }
    return total
}

The code reads numbers until encountering an error. This pattern is useful for reading variable-length input when you can't predict the number of values.

Source

Go package documentation

This tutorial covered the fmt.Fscanln function in Go with practical examples of reading formatted input from various sources.

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.