Go - 如何增加最大Stdin输入长度?

时间:2015-12-09 21:33:06

标签: go

在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())
}

3 个答案:

答案 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
        }
    }
}