0
0
GoHow-ToBeginner · 3 min read

How to Use bufio.Scanner in Go: Simple Guide with Examples

Use bufio.NewScanner to create a scanner from an io.Reader like os.Stdin or a file. Then call Scan() in a loop to read input token by token, and use Text() to get the current token as a string.
📐

Syntax

The basic syntax to use bufio.Scanner involves creating a scanner from an io.Reader, then looping with Scan() to read tokens, and accessing the token with Text().

  • scanner := bufio.NewScanner(reader): creates a new scanner.
  • scanner.Scan(): advances to the next token, returns false at EOF or error.
  • scanner.Text(): returns the current token as a string.
  • scanner.Err(): checks for errors after scanning.
go
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
    token := scanner.Text()
    // use token
}
if err := scanner.Err(); err != nil {
    // handle error
}
💻

Example

This example reads lines from standard input and prints each line until you stop the input (Ctrl+D on Unix or Ctrl+Z on Windows).

go
package main

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

func main() {
    scanner := bufio.NewScanner(os.Stdin)
    fmt.Println("Enter text (Ctrl+D to end):")
    for scanner.Scan() {
        line := scanner.Text()
        fmt.Println("You typed:", line)
    }
    if err := scanner.Err(); err != nil {
        fmt.Fprintln(os.Stderr, "Error reading input:", err)
    }
}
Output
Enter text (Ctrl+D to end): Hello You typed: Hello Go is fun You typed: Go is fun
⚠️

Common Pitfalls

Common mistakes when using bufio.Scanner include:

  • Not checking scanner.Err() after the loop to catch errors.
  • Assuming Scan() reads the entire input at once; it reads token by token.
  • Using scanner.Text() after Scan() returns false, which is invalid.
  • Not setting a split function if you want tokens other than lines (default is line by line).
go
package main

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

func main() {
    input := "word1 word2 word3"
    scanner := bufio.NewScanner(strings.NewReader(input))

    // Wrong: default split is by lines, so this reads whole input as one token
    for scanner.Scan() {
        fmt.Println(scanner.Text())
    }

    // Right: set split function to ScanWords to read words
    scanner = bufio.NewScanner(strings.NewReader(input))
    scanner.Split(bufio.ScanWords)
    for scanner.Scan() {
        fmt.Println(scanner.Text())
    }
}
Output
word1 word2 word3 word1 word2 word3
📊

Quick Reference

Remember these key points when using bufio.Scanner:

  • Use bufio.NewScanner(reader) to create a scanner.
  • Call Scan() repeatedly to read tokens.
  • Use Text() to get the current token.
  • Check Err() after scanning for errors.
  • Change token type with Split() (e.g., ScanWords, ScanLines).

Key Takeaways

Create a scanner with bufio.NewScanner from an io.Reader like os.Stdin or a file.
Use scanner.Scan() in a loop to read input token by token, usually line by line by default.
Get the current token as a string with scanner.Text() after each Scan call.
Always check scanner.Err() after the loop to catch any reading errors.
Change the tokenization behavior with scanner.Split() if you want words or custom tokens.