Go - 从重定向的 .txt 文件获取输入时,Scanf 和 ReadString 与换行符发生冲突

标签 go

我很想知道在从重定向的标准输入读取时,Go 的 ReadString 和 Scanf 函数是否存在冲突。仅供引用,开发是在 Ubuntu 上完成的。

我目前有一个递归运行的递归函数,在每次迭代中,它都会要求用户输入要测试的整数数量,然后在新创建的“测试用例”对象中完成测试 session 。因此,这是该函数的以下代码:

func (T *Test) Testing() {

if I == T.N {
    return
} else {
    //ask for number of integers per testcase
    var input string
    x:=0

    _,err = fmt.Scanf("%v\n", &x)


    //check for correct user input first
    if err != nil {
        fmt.Println("Error: ", err, "LOL")
        ProgramExit()
    }


    //receive string as input (to accomodate the itegers that are going to be put in a line, with space-seperated integers), terminate at newline
    input,err = in.ReadString('\n')

    input = strings.Trim(input, "\n")

    //check for correct user input first
    if err != nil {
        fmt.Println("Error: ", err, "Errorororo")
        ProgramExit()
    }

    //split any spaces in the input
    input_array := strings.Split(input, " ") 

    if l := len(input_array); l!=x {
        fmt.Printf("inconsistent length of input! Inputted number of integers is %v, being ", l)
        fmt.Println(input_array)
        os.Exit(1)
    } 

    //make new TestCase object, with its sum and i zeroed first
    T.Tst[I] = &TestCase{x,make([]int,x),0,0} 

    //fill TestCase object
    T.Tst[I].Fill(input_array) 

    //increase I
    I++ 

//this is where println could be added to check for iterations

    //iterate by doing recursion back to method, instead of doing a for loop
    T.Testing() 
}

需要说明的是,ProgramExit()只是一个在出错时退出整个程序的函数。而 Fill() 是一个使用 input_array 的数据填充 T 对象的函数。

现在我的问题是,当我使用上述循环运行程序时,它可以成功读取我手动键入以下命令行的输入:

(输入格式为:

测试用例数量

测试用例 1 的整数个数

测试用例 1 的输入整数数量

测试用例 2 的整数个数

测试用例 2 的输入整数数量

...

)

2
4
3 -1 1 14
5
9 6 -53 32 16

然而,当我将相同的输入放入 .txt 文件并将其重定向为我的程序的输入时,它会出现 EOF 错误,这似乎是在函数的第二次迭代期间发生的(即当它尝试读入时对于第二个测试用例对象)。这是我在 CLI 中获得的输出:

$ main < data.txt
0
Error:  EOF LOL
Incorrect input! needs to be an integer input!

这是当我为每次成功的迭代放置一个 println 函数以打印出 I 的值(第 I 次迭代)时的输出

$ main < data.txt
1
0
Error:  EOF LOL
Incorrect input! needs to be an integer input!

因此,我的函数似乎确实在正确迭代,但不幸的是,在使用 ReadString 读取整行后,Scanf 会将下一行读取为换行符(或 EOF),而不是正确读取下一行。 (当我手动输入整数时不会发生这种情况)。

任何人都可以帮助指出我执行此操作的功能是否存在问题,或者是否有其他方法可以正确执行此操作? (请注意,我正在为挑战而开发这个,在这个挑战中,for 循环是不允许的,哈哈)

提前致谢!

最佳答案

我的猜测是 Scanf正在将您在第一次迭代后最后留下的 \n 视为 EOF。

通过查看您的代码,很难猜测您在哪里遇到该错误。 但或许可以试试;

_,err = fmt.Scanf("%v%c", &x)

代替

_,err = fmt.Scanf("%v\n", &x)

并确保您的文本文件的格式符合预期(注意换行符)。或者使用更宽容的扫描仪(见下文),

Scanf scans text read from standard input, storing successive space-separated values into successive arguments as determined by the format. It returns the number of items successfully scanned. If that is less than the number of arguments, err will report why. Newlines in the input must match newlines in the format. The one exception: the verb %c always scans the next rune in the input, even if it is a space (or tab etc.) or newline.

参见 ReadString文档;

ReadString reads until the first occurrence of delim in the input, returning a string containing the data up to and including the delimiter. If ReadString encounters an error before finding a delimiter, it returns the data read before the error and the error itself (often io.EOF). ReadString returns err != nil if and only if the returned data does not end in delim. For simple uses, a Scanner may be more convenient.

您也可能从 ReadString 获取 EOF,同样,很难说查看您的输出,因为它既没有您的调试日志(LOL 等)

如果您打印它实际​​读取的内容,可能会有所帮助。我会考虑使用 Scanner相反。

关于Go - 从重定向的 .txt 文件获取输入时,Scanf 和 ReadString 与换行符发生冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42314190/

相关文章:

go - Go中返回无效结构的惯用方式

postgresql - 如何从表 GORM 中获取工资列的总和

go - 如何使用 Go 每 10 秒读取一个大文件的最后一行

go - Protocol Buffer 序列化 Golang

google-app-engine - go -mux,为什么路由没有解析?

angularjs - 没有 urlRouterProvider.otherwise 的 ui 路由

go - 想要选择一个随机数并且在所有数字都通过之前不要再次选择它

go - 将多个二进制文件构建到当前目录

reactjs - 服务器重定向不适用于 ReactJS 代理服务器

struct - 如何解决 "type interface has no field or method"错误?