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 '
'
}