英文:
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('\n')
fmt.Printf("Input Char Is : %v", 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论