9

我正在学习围棋。

我的程序应该从标准输入读取数据,直到我输入一个带有单个句点的行。

package main

import (

  "os"
  "fmt"
  "bufio"

)

func main(){

  in    := bufio.NewReader(os.Stdin)
  input := ""

  for input != "." {
    input, err := in.ReadString('\n')
    if err != nil {
      panic(err)
    }
  }
}

我应该如何修改我的 for 循环,以在我输入一个点时停止程序?

我试图用 for 语句实现一个 while 循环,我的方法有问题,条件错误,还是 ReadString 弄乱了我的数据?

4

4 回答 4

18

以防万一其他人遇到这个问题:

从 Go 1.1 开始,有一种更好的方法可以循环某些可用输入的行。这就是我今天将如何解决 OP 的问题:

package main

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

func main() {
    scanner := bufio.NewScanner(os.Stdin)
    for scanner.Scan() {
        line := scanner.Text()
        if line == "." {
            break
        }
        fmt.Println(line) // or do something else with line
    }
}

scanner.Text()自动去除尾随的换行符。

于 2014-06-18T22:58:53.037 回答
12

... ReadString 是否在弄乱我的数据?

不,不是。它正在阅读到下一个'\n'。这意味着上面只有一个点的行将包含数据".\n"".\r\n"取决于操作系统。

要删除行尾,我会这样做input = strings.TrimRight(input, "\r\n")

于 2013-01-07T22:57:34.950 回答
1

使用任何bufio 辅助函数的主要问题是它可能会读取更多超出停止字符的数据。它读取缓冲区大小的所有可用输入。在并发访问 os.Stdin 的情况下,下一个读取器可能会错过一些之前由 bufio 读取的输入。下面是我的非缓冲“草稿”代码,用于勾画从输入流中读取直到CR字符的所有字符的并发安全方法。'\n' ('\n')

package main

import "os"

// echo a line in input to output
// you may add exit signal in copy loop as well
func main() {
    const BUF_SIZE = 128
    in := os.Stdin
    out := os.Stdout
    bufOut := make([]byte, BUF_SIZE)
    n := 0
    for {    // copy loop 
        // non buffered byte-by-byte
        if _, err := in.Read(bufOut[n : n+1]); err != nil {
            break
        }
        if bufOut[n] == 0xa || n == BUF_SIZE { // reached CR or size limit 
            if _, err = out.Write(bufOut[0 : n+1]); err != nil {
                break
            }
            n = 0
        } else {
            n++
        }
    }
}
于 2015-09-21T15:58:50.217 回答
0

刚刚注意到主题内的问题与标题中的问题不同。有问题的初始样本的错误是在循环内重新声明了输入变量。这就是为什么您的条件检查永远不会到达退出点的原因。

于 2015-09-22T20:32:01.927 回答