在Go中使用标准输入读取时,建议允许超过1024个字符的方法是什么?
例如,使用bufio.Scanner
的此代码的最大输入长度为1024。
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
input := scanner.Text()
fmt.Println(input)
}
在一些建议的答案后更新...... 对不起伙计们 - 我一定是做错了什么,或者说错了问题。我尝试了两个建议,但仍然看到同样的问题。以下是代码的更新版本。症状是扫描仪在第1024个字符后不接受输入。例如尝试运行它然后粘贴一个长度为1025个字符的字符串,并且它将在字符1024之后停止接受输入。
package main
import (
"bufio"
"bytes"
"fmt"
"log"
"os"
)
func main() {
var buffer bytes.Buffer
scanner := bufio.NewScanner(os.Stdin)
for {
done := scanner.Scan()
buffer.WriteString(scanner.Text())
if done == true {
if scanner.Err() != nil {
log.Fatal("Error scanning input")
}
break
}
}
fmt.Println(buffer.String())
}
答案 0 :(得分:5)
您忽略了scanner.Scan()
的返回值bool
,表示您是否已到达终点。
具体做法是:
扫描停止时返回false,或者到达结尾 输入或错误。在Scan返回false之后,Err方法将会 返回扫描期间发生的任何错误,除非是 io.EOF,Err将返回nil。
所以你需要在循环中继续运行scanner.Scan()
,直到它返回false,然后检查.Err()
以确保你没有因为非EOF错误而停止扫描。
答案 1 :(得分:1)
此代码的主要问题是如果扫描程序完成,则scanner.Scan的返回值不是true
,而如果扫描程序没有完成,则true
的返回值。
虽然我们正在解决这个问题,但是,让我们整理另一件事,因为你不需要使用
if done == true
但可以简单地做
if done
另外,请记住done = Scanner.Text()
,并作为终止条件,我们可以很好地整理代码:
for scanner.Scan() { // This does what you want, looping until scanner
// is no longer true.
buffer.WriteString(scanner.Text())
}
if err := scanner.Err(); err != nil { // Let's hold on to err...
log.Fatalf("Error scanning input: %s", err) // and use it here.
}
你要丢弃很多行,而你只在循环结束时检查一次Err()。不需要休息。
希望这对你有用,如果你需要别的东西,请给我发一条。
编辑:还有两件事需要注意。
1)bufio.Scanner.Scan()
将吃掉所有分隔符标记。也许这没关系,或者你想继续加入它们。
2)如果您的SplitFunc错误,或者有人正在为您的SplitFunc制作糟糕的输入,bufio.Scanner.Scan()
可能会发生混乱,如果缓冲区太大,bytes.Buffer.WriteString()
可能会发生混乱。如果您在生产系统中使用这些,请确保以任何有意义的方式处理这些恐慌。
答案 2 :(得分:0)
您可以执行此操作,而不是使用Scanner
...
reader := bufio.NewReaderSize(os.Stdin, 65536)
line, isPrefix, err := reader.ReadLine()
写一个帮助函数来继续阅读,直到你读完一行......
func ReadLine(reader *bufio.Reader) (string, error) {
result := ""
for {
line, isPrefix, err := reader.ReadLine()
if err != nil {
return result, err
}
result += string(line)
if !isPrefix {
return result, nil
}
}
}