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.
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.
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.
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.
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.
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.
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.
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
This tutorial covered the fmt.Fscanln function in Go with practical
examples of reading formatted input from various sources.
Author
List all Golang tutorials.