Golang user input: Scan, Scanf, and bufio for stdin

How to take input in golang and golang get user input from stdin: fmt.Scan Scanln Scanf for typed tokens, golang read input with bufio; go read user input and how to get user input in go with line-based reads; input golang newline pitfalls.

Published

Updated

Read time 3 min read

Reviewed byDeepak Prasad

Golang user input: Scan, Scanf, and bufio for stdin

Questions like how to take input in golang, golang get user input, go read user input, or user input golang all point at os.Stdin together with fmt or bufio. The fmt functions split on whitespace and decode into variables; bufio is better when you need a full line or want to control delimiters. This article covers golang read input and parsing multiple values in one go—related to variadic-style APIs like fmt.Scanln (see variadic functions in Go).

Tested with Go 1.24 on Linux.


golang read input with fmt.Scan, Scanln, and Scanf

fmt.Scan, fmt.Scanln, and fmt.Scanf read from standard input, skipping leading spaces and splitting fields on whitespace. Scanln stops at a newline; Scan can leave a trailing newline in the buffer, which surprises people learning how to get user input in go.

go
package main

import "fmt"

func main() {
	var first, last string
	var age int
	fmt.Println("Enter first name, last name, and age (space-separated):")
	n, err := fmt.Scan(&first, &last, &age)
	if err != nil {
		fmt.Println("read error:", err)
		return
	}
	fmt.Printf("read %d fields: %s %s (%d)\n", n, first, last, age)
}

Run locally, then type Ada Lovelace 36 and press Enter. The field order in the Scan call must match the order you type.

For typed patterns on one line, Scanf uses a format string like printf:

go
package main

import "fmt"

func main() {
	var base, height float64
	fmt.Println("Enter base and height (two floats, space-separated):")
	if _, err := fmt.Scanf("%f %f", &base, &height); err != nil {
		fmt.Println("read error:", err)
		return
	}
	fmt.Printf("area=%.2f\n", 0.5*base*height)
}

Use %f or %g for floats; width modifiers such as %2f are rarely what you want for scanning.


Line-based input golang (bufio and os.Stdin)

When input is a sentence or you need stable “one line = one string” behavior, attach a bufio.Scanner to os.Stdin (or a bufio.Reader and ReadString('\n')):

go
package main

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

func main() {
	fmt.Println("Describe your project in one line, then press Enter:")
	line, err := bufio.NewReader(os.Stdin).ReadString('\n')
	if err != nil {
		fmt.Println("read error:", err)
		return
	}
	line = strings.TrimSuffix(line, "\n")
	fmt.Println("You wrote:", line)
}

For many lines until EOF, loop scanner.Scan() and use scanner.Text(); set scanner.Split(bufio.ScanWords) if you want token-by-token reading instead of whole lines.


Summary

Golang user input from the terminal is stdin: fmt.Scan, Scanln, and Scanf answer how to take input in golang when values are short and whitespace-separated; they are the usual get user input golang path for quick CLIs. golang read input for full lines belongs in bufio with ReadString or a Scanner. Watch newline interactions between Scan and later reads, and validate error returns from every read.


References


Frequently Asked Questions

1. What is the difference between fmt.Scan and bufio.Scanner for user input golang?

fmt.Scan and Scanln split on whitespace and parse into typed variables; they are awkward for full sentences. bufio.Scanner or ReadString reads raw text (usually one line at a time) so you can split or parse yourself.

2. Why does my second fmt.Scan call seem skipped?

Scan leaves the trailing newline in the buffer when the user presses Enter; the next Scan may read an empty token. Use Scanln, read the rest with a bufio.Reader, or use Scanner for line-based input.

3. How do I read two floats on one line in Go?

Use fmt.Scanf with a format like "%f %f" and pointers to both variables, or fmt.Scan with two *float64 arguments if the line only contains the numbers.
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive …