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.