Golang读取行,然后从同一bufio.Scanner读取单词

I'm trying to read a line and words from stdin using the same bufio.Scanner instance.

I've tried using two bufio.Scanner first but it the second scanner can't read anything.

package main

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

func main() {
    r := strings.NewReader("first line
2nd line")
    scanner := bufio.NewScanner(r)
    scanner2 := bufio.NewScanner(r)

    fmt.Println("scanning line")
    if scanner.Scan() {
        fmt.Println("Scanned line: ", scanner.Text())
    }

    if err := scanner.Err(); err != nil {
        fmt.Fprintln(os.Stderr, "reading standard input:", err)
    }

    scanner2.Split(bufio.ScanWords)
    fmt.Println("scanning word")
    if scanner2.Scan() {
        // i'm expecting that this would read "2nd"
        fmt.Println("Scanned word: ", scanner2.Text())
    }

    if err := scanner2.Err(); err != nil {
        fmt.Fprintln(os.Stderr, "reading standard input:", err)
    }
}

Then I tried setting the scanner.Split , but it doesn't allow calling the scanner.Split after calling scanner.Scan.

Is there a way that I can read a line and then words from the same bufio.Scanner?

First. You can't read same line from reader multiple times. You read it once reader going to be empty, that is why the second scanner can't read anything. In your example you are using strings.Reader no os.Stdin. You can use something like io.TeeReader to duplicate to read the reader more times but this isn't your case.

Second. You cant call scanner.Split after scanner.Scan was called, you need to create a new scanner with os.Stdin as input.

For example:

// this gonna read from stdin complete lines
scanner := bufio.NewScanner(os.Stdin)

// scanning lines until Q is typed
for scanner.Scan() {
    t := scanner.Text()

    if t == "Q" {
        break
    }
    fmt.Println(scanner.Text())
}

// new scanner to read but this time words
scanner = bufio.NewScanner(os.Stdin)
scanner.Split(bufio.ScanWords)

for scanner.Scan() {
    fmt.Println(scanner.Text()) // Println will add back the final '
'
}