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.