2017-08-28 81 views
2

输入我有这样的Go代码:阅读从标准输入中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 

一切OK。但现在,如果我创建每行一个读者:

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

为什么会发生?

回答

3

对于简单的用途,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 

我希望这有助于。

+0

这是完美的!非常感谢你 –

+0

不客气。 –