【问题标题】:Reading input from stdin in golang从 golang 中的标准输入读取输入
【发布时间】:2018-02-05 10:17:03
【问题描述】:

我有这个 go 代码:

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

一切正常。但是现在,如果我每行创建一个阅读器:

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 错误,在第二行读取。

为什么会这样?

【问题讨论】:

    标签: go stdin


    【解决方案1】:

    对于简单的用途,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 字节,它将起作用。


    如果 ReadString 在找到分隔符之前遇到错误,它 返回错误前读取的数据和错误本身(通常 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
    

    我希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-24
      • 2016-12-30
      • 1970-01-01
      • 1970-01-01
      • 2017-09-07
      • 2013-03-30
      • 2012-02-17
      • 1970-01-01
      相关资源
      最近更新 更多