Golang fmt.Fscan function
last modified May 8, 2025
This tutorial explains how to use the fmt.Fscan function in Go.
We'll cover input scanning basics with practical examples of reading data.
The fmt.Fscan function reads formatted input from an io.Reader. It scans text from the reader, storing successive space-separated values. Values are stored in the pointers passed as additional arguments.
In Go, fmt.Fscan is part of the fmt package's scanning functions.
It's useful for reading structured data from files, strings, or network connections.
The function returns the number of items successfully scanned.
Basic Fscan usage
The simplest use of fmt.Fscan reads values from a string reader.
This example demonstrates basic scanning of different data types.
Note: Values must be passed as pointers to be modified.
package main
import (
"fmt"
"strings"
)
func main() {
input := "42 3.14 hello"
reader := strings.NewReader(input)
var i int
var f float64
var s string
n, err := fmt.Fscan(reader, &i, &f, &s)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf("Scanned %d items: %d, %f, %q\n", n, i, f, s)
}
The code reads an integer, float, and string from the input string. The function returns the count of successfully scanned items and any error.
Reading from standard input
fmt.Fscan can read directly from standard input using os.Stdin.
This example shows interactive input scanning from the console.
package main
import (
"fmt"
"os"
)
func main() {
var name string
var age int
fmt.Print("Enter your name and age: ")
n, err := fmt.Fscan(os.Stdin, &name, &age)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf("Scanned %d items\n", n)
fmt.Printf("Hello %s, you are %d years old\n", name, age)
}
The program waits for user input from the terminal. Values are separated by whitespace. The function reads until it fills all provided variables.
Reading from a file
fmt.Fscan is commonly used to read structured data from files.
This example demonstrates reading multiple records from a text file.
package main
import (
"fmt"
"os"
)
type Person struct {
Name string
Age int
}
func main() {
file, err := os.Open("data.txt")
if err != nil {
fmt.Println("Error opening file:", err)
return
}
defer file.Close()
var people []Person
for {
var p Person
n, err := fmt.Fscan(file, &p.Name, &p.Age)
if err != nil || n != 2 {
break
}
people = append(people, p)
}
fmt.Println("People data:")
for _, p := range people {
fmt.Printf("%s: %d\n", p.Name, p.Age)
}
}
The code reads name-age pairs from a file until EOF. Each line in the file should contain a name and age separated by whitespace.
Handling different data formats
fmt.Fscan can parse various data formats automatically.
This example shows scanning different numeric formats and strings.
package main
import (
"fmt"
"strings"
)
func main() {
input := "0x1A 1.5e3 true Golang"
reader := strings.NewReader(input)
var hex int
var sci float64
var flag bool
var lang string
n, err := fmt.Fscan(reader, &hex, &sci, &flag, &lang)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf("Scanned %d items:\n", n)
fmt.Printf("Hex: %d\n", hex)
fmt.Printf("Scientific: %f\n", sci)
fmt.Printf("Boolean: %t\n", flag)
fmt.Printf("String: %q\n", lang)
}
The function automatically converts hexadecimal, scientific notation, and boolean values. It handles different base representations of numbers.
Reading multiple lines
fmt.Fscan can read across multiple lines in the input.
This example demonstrates reading a multi-line input structure.
package main
import (
"fmt"
"strings"
)
func main() {
input := `Product: Laptop
Price: 999.99
InStock: true`
reader := strings.NewReader(input)
var product string
var price float64
var inStock bool
// Skip labels
var label string
fmt.Fscan(reader, &label, &product)
fmt.Fscan(reader, &label, &price)
fmt.Fscan(reader, &label, &inStock)
fmt.Printf("%s: $%.2f (In stock: %t)\n",
product, price, inStock)
}
The code reads labeled data spread across multiple lines. It skips the labels while storing the actual values in variables.
Error handling in Fscan
Proper error handling is crucial when using fmt.Fscan.
This example shows comprehensive error checking for input scanning.
package main
import (
"fmt"
"strings"
)
func main() {
tests := []string{
"100 200", // valid
"100 abc", // invalid
"100 200 300", // extra
"100", // insufficient
}
for _, input := range tests {
reader := strings.NewReader(input)
var a, b int
n, err := fmt.Fscan(reader, &a, &b)
fmt.Printf("Input: %q\n", input)
fmt.Printf("Scanned %d items\n", n)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Printf("Values: %d, %d\n", a, b)
}
fmt.Println("-----")
}
}
The code tests various input scenarios and shows how errors are reported. Different types of input problems produce different error conditions.
Advanced Fscan usage
fmt.Fscan can be combined with custom io.Reader implementations.
This example shows scanning from a custom data source.
package main
import (
"fmt"
"io"
)
type Rot13Reader struct {
r io.Reader
}
func (r Rot13Reader) Read(p []byte) (n int, err error) {
n, err = r.r.Read(p)
for i := 0; i < n; i++ {
switch {
case p[i] >= 'A' && p[i] <= 'Z':
p[i] = (p[i]-'A'+13)%26 + 'A'
case p[i] >= 'a' && p[i] <= 'z':
p[i] = (p[i]-'a'+13)%26 + 'a'
}
}
return
}
func main() {
input := "Uryyb Jbeyq"
rot := Rot13Reader{strings.NewReader(input)}
var hello, world string
fmt.Fscan(&rot, &hello, &world)
fmt.Println(hello, world) // Output: Hello World
}
The custom Rot13Reader decrypts text before scanning. This demonstrates
how fmt.Fscan can work with any io.Reader implementation.
Source
This tutorial covered the fmt.Fscan function in Go with practical
examples of reading formatted input from various sources.
Author
List all Golang tutorials.