To read user input from the terminal console in Go, you can use several methods:
fmt.Scanln()
,fmt.Scan()
,fmt.Scanf()
functions which allow you to read successive words into separate variables.bufio.Reader
struct which can read a line of the input text or a single character.bufio.Scanner
which provides a convenient interface for reading lines of text.
As usual, which method to use depends on the use case. In the next sections, we will show how to read a single or multiple lines of the user input from the console, how to read a single character, how to read data from formatted input, and finally, how to read numbers from the terminal.
Read a single line from standard input
Use fmt.Scanln()
to read a single line of text
package main
import (
"fmt"
"log"
)
func main() {
fmt.Println("input text:")
var w1, w2, w3 string
n, err := fmt.Scanln(&w1, &w2, &w3)
if err != nil {
log.Fatal(err)
}
fmt.Printf("number of items read: %d\n", n)
fmt.Printf("read line: %s %s %s-\n", w1, w2, w3)
}
Output:
input text:
ab cd ef
number of items read: 3
read line: ab cd ef-
Use bufio.Reader
to read a single line of text
package main
import (
"bufio"
"fmt"
"log"
"os"
)
func main() {
fmt.Println("input text:")
reader := bufio.NewReader(os.Stdin)
line, err := reader.ReadString('\n')
if err != nil {
log.Fatal(err)
}
fmt.Printf("read line: %s-\n", line)
}
Output:
input text:
ab cd ef
read line: ab cd ef
-
Use bufio.Scanner
to read a single line of text
package main
import (
"bufio"
"fmt"
"log"
"os"
)
func main() {
fmt.Println("input text:")
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
err := scanner.Err()
if err != nil {
log.Fatal(err)
}
fmt.Printf("read line: %s-\n", scanner.Text())
}
Output:
input text:
ab cd ef
number of items read: 3
read line: ab cd ef-
- Use the
fmt.Scanln()
function if you want to read each word of a line into a different variable, and there is a certain number of words to read, no less, no more. - Use the
bufio.Reader
if you want to read a full line of text together with the newline character. - Use the
bufio.Scanner
to read a full line of text in a convenient way without the newline character.
Read multiple lines from console
Use fmt.Scan()
to read multiple lines of text
package main
import (
"fmt"
"log"
)
func main() {
fmt.Println("input text:")
var w1, w2, w3 string
n, err := fmt.Scan(&w1, &w2, &w3)
if err != nil {
log.Fatal(err)
}
fmt.Printf("number of items read: %d\n", n)
fmt.Printf("read text: %s %s %s-\n", w1, w2, w3)
}
Output:
input text:
ab
cd
ef
number of items read: 3
read text: ab cd ef-
With the
fmt.Scan()
you can read multiple lines of text only if the line consists of a single word.
Use bufio.Reader
to read multiple lines of text
package main
import (
"bufio"
"fmt"
"log"
"os"
"strings"
)
func main() {
fmt.Println("input text:")
reader := bufio.NewReader(os.Stdin)
var lines []string
for {
line, err := reader.ReadString('\n')
if err != nil {
log.Fatal(err)
}
if len(strings.TrimSpace(line)) == 0 {
break
}
lines = append(lines, line)
}
fmt.Println("output:")
for _, l := range lines {
fmt.Println(l)
}
}
Output:
input text:
ab cd ef gh
hj kl mn op
output:
ab cd ef gh
hj kl mn op
Use bufio.Scanner
to read multiple lines of text
package main
import (
"bufio"
"fmt"
"log"
"os"
)
func main() {
fmt.Println("input text:")
scanner := bufio.NewScanner(os.Stdin)
var lines []string
for {
scanner.Scan()
line := scanner.Text()
if len(line) == 0 {
break
}
lines = append(lines, line)
}
err := scanner.Err()
if err != nil {
log.Fatal(err)
}
fmt.Println("output:")
for _, l := range lines {
fmt.Println(l)
}
}
Output:
input text:
ab cd ef gh
hj kl mn op
output:
ab cd ef gh
hj kl mn op
- Use the
fmt.Scan()
if you want to read multiple words where each word is on a separate line. - Use the
bufio.Reader
if you want to read multiple lines together with the newline character at the end of each line. - The most recommended and universal method of reading multiple lines is to use the
bufio.Scanner
, which allows you to get a list of input lines without the newline character at the end of each line.
Read a single character from terminal
Use bufio.Reader
to read a single character
package main
import (
"bufio"
"fmt"
"log"
"os"
)
func main() {
fmt.Println("input text:")
reader := bufio.NewReader(os.Stdin)
char, _, err := reader.ReadRune()
if err != nil {
log.Fatal(err)
}
fmt.Printf("read character: %c-\n", char)
}
Output:
input text:
abfd
read character: a-
Use fmt.Scanf()
to read a single character
package main
import (
"fmt"
"log"
)
func main() {
fmt.Println("input text:")
var char rune
_, err := fmt.Scanf("%c", &char)
if err != nil {
log.Fatal(err)
}
fmt.Printf("read character: %c-\n", char)
}
Output:
input text:
abcd
read character: a-
- Reading a single character is possible via the
bufio.Reader
and itsReadRune()
method, which returns the rune, the size of the rune, and the reading error. - A slightly simpler, single-line method for reading a character is to use the
fmt.Scanf()
function with the%c
.
Read formatted user input
When you want to accept text only of a specific format and read certain items into variables, the best method is to use the fmt.Scanf()
function, which reads the text according to a given format.
package main
import (
"fmt"
"log"
)
func main() {
fmt.Println("input text:")
var name string
var country string
n, err := fmt.Scanf("%s is born in %s", &name, &country)
if err != nil {
log.Fatal(err)
}
fmt.Printf("number of items read: %d\n", n)
fmt.Println(name, country)
}
input text:
Anna is born in Germany
number of items read: 2
Anna Germany
Read numbers from user input
Reading numbers from the terminal console can be done by using the fmt.Scanf()
or fmt.Scan()
functions. The first one requires an input format - for numbers, it is %d
for integers or %f
for floating-point numbers. The second, which is simpler, does not require a format but discovers itself how the input data should be parsed to match the output variable.
Use fmt.Scanf()
to read a number
package main
import (
"fmt"
"log"
)
func main() {
fmt.Println("input number:")
var number int64
_, err := fmt.Scanf("%d", &number)
if err != nil {
log.Fatal(err)
}
fmt.Printf("read number: %d\n", number)
}
Output:
input number:
8
read number: 8
Use fmt.Scan()
to read a number
package main
import (
"fmt"
"log"
)
func main() {
fmt.Println("input number:")
var number int64
_, err := fmt.Scan(&number)
if err != nil {
log.Fatal(err)
}
fmt.Printf("read number: %d\n", number)
}
Output:
input number:
8
read number: 8