在 golang 中从 stdin 读取输入
Reading input from stdin in golang
我有这个代码:
func readTwoLines() {
reader := bufio.NewReader(os.Stdin)
line, _ := reader.ReadString('\n')
fmt.Println(line)
line, _ = reader.ReadString('\n')
fmt.Println(line)
}
对于输入:
hello
bye
输出是:
hello
bye
一切正常。但是现在,如果我每行创建一个 reader:
func readTwoLines() {
line, _ := bufio.NewReader(os.Stdin).ReadString('\n')
fmt.Println(line)
line, err := bufio.NewReader(os.Stdin).ReadString('\n')
if err != nil {
fmt.Println(err)
}
fmt.Println(line)
}
阅读第二行时出现EOF
错误。
为什么会这样?
对于简单的使用,Scanner
可能更方便。
你不应该使用两个阅读器,第一次读取,缓冲 4096 字节的输入:
// NewReader returns a new Reader whose buffer has the default size.
func NewReader(rd io.Reader) *Reader {
return NewReaderSize(rd, defaultBufSize)
}
和defaultBufSize = 4096
甚至您的输入包含 4000 个字节,第二次读取仍然没有任何可读取的内容。
但如果您输入超过 4096 字节的输入,它将起作用。
If ReadString encounters an error before finding a delimiter, it
returns the data read before the error and the error itself (often
io.EOF).
这是设计使然,请参阅文档:
// ReadString reads until the first occurrence of delim in the input,
// returning a string containing the data up to and including the delimiter.
// If ReadString encounters an error before finding a delimiter,
// it returns the data read before the error and the error itself (often io.EOF).
// ReadString returns err != nil if and only if the returned data does not end in
// delim.
// For simple uses, a Scanner may be more convenient.
func (b *Reader) ReadString(delim byte) (string, error) {
bytes, err := b.ReadBytes(delim)
return string(bytes), err
}
试试这个:
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
fmt.Println(scanner.Text()) // Println will add back the final '\n'
}
if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, "reading standard input:", err)
}
}
运行:
go run m.go < in.txt
输出:
hello
bye
in.txt
文件:
hello
bye
希望对您有所帮助。
我有这个代码:
func readTwoLines() {
reader := bufio.NewReader(os.Stdin)
line, _ := reader.ReadString('\n')
fmt.Println(line)
line, _ = reader.ReadString('\n')
fmt.Println(line)
}
对于输入:
hello
bye
输出是:
hello
bye
一切正常。但是现在,如果我每行创建一个 reader:
func readTwoLines() {
line, _ := bufio.NewReader(os.Stdin).ReadString('\n')
fmt.Println(line)
line, err := bufio.NewReader(os.Stdin).ReadString('\n')
if err != nil {
fmt.Println(err)
}
fmt.Println(line)
}
阅读第二行时出现EOF
错误。
为什么会这样?
对于简单的使用,Scanner
可能更方便。
你不应该使用两个阅读器,第一次读取,缓冲 4096 字节的输入:
// NewReader returns a new Reader whose buffer has the default size. func NewReader(rd io.Reader) *Reader { return NewReaderSize(rd, defaultBufSize) }
和defaultBufSize = 4096
甚至您的输入包含 4000 个字节,第二次读取仍然没有任何可读取的内容。 但如果您输入超过 4096 字节的输入,它将起作用。
If ReadString encounters an error before finding a delimiter, it returns the data read before the error and the error itself (often io.EOF).
这是设计使然,请参阅文档:
// ReadString reads until the first occurrence of delim in the input,
// returning a string containing the data up to and including the delimiter.
// If ReadString encounters an error before finding a delimiter,
// it returns the data read before the error and the error itself (often io.EOF).
// ReadString returns err != nil if and only if the returned data does not end in
// delim.
// For simple uses, a Scanner may be more convenient.
func (b *Reader) ReadString(delim byte) (string, error) {
bytes, err := b.ReadBytes(delim)
return string(bytes), err
}
试试这个:
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
fmt.Println(scanner.Text()) // Println will add back the final '\n'
}
if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, "reading standard input:", err)
}
}
运行:
go run m.go < in.txt
输出:
hello
bye
in.txt
文件:
hello
bye
希望对您有所帮助。