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

时间:2017-02-18 10:53:54

标签: go

我真的想知道在从重定向的标准输入读取时是否存在与Go的ReadString和Scanf函数有关的冲突。仅供参考,开发工作在Ubuntu上进行。

我目前有一个递归运行的递归函数,在每次迭代中它要求用户输入将要测试的整数的数量,然后在新创建的' testcase中完成测试会话#39;宾语。所以这里是函数的以下代码:

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对象的函数。

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

(输入格式为:

num个测试用例

testcase 1的整数数

testcase 1的输入整数数

testcase 2的整数数

testcase 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的值(第一次迭代)时,这就是输出

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

所以看起来我的函数正在迭代正确但不幸的是,在用ReadString读取整行之后,Scanf会将下一行读作换行符(或EOF),而不是正确读取下一行。 (当我输入整数手动时,不会发生这种情况)。

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

提前致谢!

2 个答案:

答案 0 :(得分:2)

我的猜测是Scanf将第一次迭代结束后留下的\n视为EOF。

很难猜到你在哪里得到那个错误,看着你的代码。 但也许试试;

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

而不是

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

确保您的文本文件已按预期格式化(谨防新行)。或使用更宽容的扫描仪(见下文),

  

Scanf扫描从标准输入读取的文本,将连续的空格分隔值存储到由格式确定的连续参数中。它返回成功扫描的项目数。如果这小于参数的数量,则错误将报告原因。 输入中的换行符必须与格式中的换行符匹配。一个例外:动词%c始终扫描输入中的下一个符文,即使它是空格(或制表符等)或换行符。

请参阅ReadString doc;

  

ReadString读取直到输入中第一次出现delim,返回包含数据的字符串,包括分隔符。如果ReadString在找到分隔符之前遇到错误,它将返回错误之前读取的数据和错误本身(通常是io.EOF)。当且仅当返回的数据不以delim结尾时,ReadString才返回err!= nil。对于简单的用途,扫描仪可能更方便。

你可能也会从ReadString获得EOF,再次,很难说你看看你的输出,因为它没有你的调试日志(LOL等)。

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

答案 1 :(得分:0)

感谢那些试图帮助的人!在谷歌再次搜索后,我找到了更正确的输入整数行的方法。显然,这里已经讨论过一种方法:Read a set of integers separated by space in Golang

我基本上替换了我的字符串输入法,而是在测试用例值的每次迭代中进行fmt.Scan()的迭代,以正确输入整数。再一次非常感谢那些试图提供帮助的人,并且道歉我很快就找不到谷歌的答案了!