Learning Golang: Scan, Scanln and Scanf
This is part 18 of my journey learning Golang.
Command line interface
When building programs that run on a terminal it is often useful to be able to allow the user to enter text.
For instance the ssh-keygen
utility will prompt for a path and a passphrase.
1❯ ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
2Generating public/private rsa key pair.
3Enter file in which to save the key (/home/fernando/.ssh/id_rsa): /tmp/test_rsa
4Enter passphrase (empty for no passphrase):
5Enter same passphrase again:
Scan
The Scan
method of the fmt
package will read a single space-separated token (like a single word) from the standard
input device (which is usually the console).
Scan
expects an address as its argument. That can be provided by using the &
symbol in front of a variable name.
For example:
1package main
2
3import (
4 "fmt"
5)
6
7func main() {
8 fmt.Print("What is your first name? ")
9 var response string
10 fmt.Scan(&response)
11 fmt.Printf("Hello, %v!\n", response)
12}
Source: learning-go/scanning/scan.go
This program, when executed, will wait for the user to enter a line of text, and then it will take the first word of that line (until it finds a space or the end of the line):
1❯ go run ./scanning/scan.go
2What is your first name? Jane
3Hello, Jane!
If more than one word is entered, only the first one is read by Scan
. The remainder is left in the console and can be
read by another Scan
call. For example:
1❯ go run ./scanning/scan.go
2What is your first name? Jane Doe
3Hello, Jane!
4
5❯ Doe
6zsh: Doe: command not found...
Notice how the rest of the input was left in the console, and was read by the terminal after the program finished.
Scanln
The Scanln
method is similar to Scan
. It will also read space-separated tokens. Two differences are:
- it will stop at a newline character;
- it requires a newline or EOF character after the last item.
Scanf
According to the documentation:
Scanf scans text read from standard input, storing successive space-separated values into successive arguments as determined by the format. It returns the number of items successfully scanned. If that is less than the number of arguments, err will report why. Newlines in the input must match newlines in the format. The one exception: the verb %c always scans the next rune in the input, even if it is a space (or tab etc.) or newline.
Scanf
adds finer-grained control (via a format string) to input parsing.
Reading full lines from the console
If the program requires reading a full line from standard input, instead of using the fmt
package it is better to use
the bufio
package.
This article teaches how to do that: Reading in Console Input in Golang.
Takeaways
The “Scan” family of methods in the fmt
package is meant for reading tokens and other kinds of delimited values from
standard input.
The bufio
package is better suited for interacting with users via a command line interface.
comments powered by Disqus