有没有类似于 getchar() 直到 EOF 的 Go 函数?

huangapple go评论64阅读模式
英文:

Is there a Go function which is similar to getchar() until EOF?

问题

我是你的中文翻译助手,以下是翻译好的内容:

我是Go的新手。我知道它有一些扫描函数:scan、sscan、scanf、sscanf等等。

但是所有这些函数,我引用一句话:“存储连续的以空格分隔的值”,有些将换行符视为空格。但这不是我需要的。

我已经尝试了以下代码:

reader := bufio.NewReader(os.Stdin)
input, _ := reader.ReadString('\n')
fmt.Printf("Input Char Is : %v", string([]byte(input)[0]))

但是这在换行符后停止,而不是EOF。

我需要一种方法来逐个字符地扫描,直到EOF。
在C语言中,我会这样写:

while (getChar()){
    //做一些操作
}

在Go语言中,相当于这个的是什么?

英文:

I'm new at Go. I know it has some scanning functions: scan, sscan, scanf, sscanf and others.

but all of them, and I quote : "storing successive space-separated values", some treat new lines as spaces. but this is not I need.

I've already tried this:

<!-- language: lang-go -->

reader := bufio.NewReader(os.Stdin)
input, _ := reader.ReadString(&#39;\n&#39;)
fmt.Printf(&quot;Input Char Is : %v&quot;, string([]byte(input)[0]))

but this stops after new line not EOF.

I need a way to scan single chars one at a time until EOF.
in C I would write:

<!-- language: lang-c -->

while (getChar()){
//do stuff 
}

What is the equivalent to this in Go?

答案1

得分: 4

有两种技术可以考虑:

1. ioutil.ReadAll

根据文档:

> ReadAll 从 r 中读取直到出现错误或 EOF,并返回它读取的数据。成功的调用返回 err == nil,而不是 err == EOF。因为 ReadAll 被定义为从 src 读取直到 EOF,所以它不会将来自 Read 的 EOF 视为要报告的错误。

例如:

byteSlice, err := ioutil.ReadAll(os.Stdin)
if err != nil {
    log.Fatal(err)
}

for b := range byteSlice {
    // 做一些操作
}

对于除文件以外的 io.Reader(例如网络连接),不应使用此方法,因为可能永远不会出现 EOF 条件,从而导致程序永远阻塞。

在你的情况下,如果你不介意将所有字节保存在内存中,使用这种技术是可以的。

2. io.ByteReader

另一种方法是通过 bufio.Reader 使用 io.ByteReader 接口,像这样:

reader := bufio.NewReader(os.Stdin)
for {
    b, err := reader.ReadByte()
    if err != nil {
        break
    }

    // 做一些操作
}

这是最接近 C 的 getchar() 循环的方法。

英文:

Two techniques pop to mind:

1. ioutil.ReadAll

From the documentation:

> ReadAll reads from r until an error or EOF and returns the data it read. A successful call returns err == nil, not err == EOF. Because ReadAll is defined to read from src until EOF, it does not treat an EOF from Read as an error to be reported.

For example:

byteSlice, err := ioutil.ReadAll(os.Stdin)
if err != nil {
    log.Fatal(err)
}

for b := range byteSlice {
    // do stuff
}

This is should not be used for io.Reader that are anything else than files (for example network connections) because an EOF condition may never happen, and so the program may block forever.

In your case, it is fine to use this technique, especially if you don't mind holding all the bytes in memory.

2. io.ByteReader

An alternative is also to use the io.ByteReader interface through a bufio.Reader, like this:

reader := bufio.NewReader(os.Stdin)
for {
    b, err := reader.ReadByte()
    if err != nil {
        break
    }

    // do stuff
}

This is the closest to C's getchar() loop.

huangapple
  • 本文由 发表于 2014年11月8日 07:10:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/26811600.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定