如何打印通过stdin引入的行数?

时间:2016-07-26 20:18:57

标签: go

我有以下程序,我希望显示特定引入行从stdin出现的次数:

package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    counts := make(map[string]int)
    input := bufio.NewScanner(os.Stdin)
    for input.Scan() {
        counts[input.Text()]++
    }
    // NOTE: ignoring potential errors from input.Err()
    for line, n := range counts {
        if n > 1 {
            fmt.Printf("%d\t%s\n", n, line)
        }
    }
}

当我运行该程序时,它允许我输入字符串,但即使我按下回车,我也没有得到任何反馈。

我在这里缺少什么?我相信它会在第一个for中受到谴责。

3 个答案:

答案 0 :(得分:0)

尝试此操作 - 将以下文本保存在/tmp/input.txt或其他本地文件中:

Line A
Line B
Line B
Line A
Line C
Line B

现在将该文件的内容作为标准输入传递给您的程序 - 例如在/tmp/q.go中: cat /tmp/input.txt | go run /tmp/q.go 输出应为:

$ cat /tmp/input.txt | go run /tmp/q.go
2   Line A
3   Line B

答案 1 :(得分:0)

您的代码首先获取所有行,然后在结尾打印结果(\\location\builds678\INTEGRATION\BOOT.FAN.1.2-00179-M1234LAB-1 ) 1 - 如果按Enter键需要每行的反馈:编辑第一个循环:

EOF

就像这个工作示例代码:

for input.Scan() {
    txt := input.Text()
    counts[txt]++
    fmt.Println("counts[", txt, "] =", counts[txt])
}

2-如果您希望在数据输入结束时得到结果,您有两个选择:
选项A:在终端(命令提示符)的行末尾按package main import ( "bufio" "fmt" "os" ) func main() { counts := make(map[string]int) input := bufio.NewScanner(os.Stdin) for input.Scan() { txt := input.Text() counts[txt]++ fmt.Println("counts[", txt, "] =", counts[txt]) } // NOTE: ignoring potential errors from input.Err() for line, n := range counts { if n > 1 { fmt.Printf("%d\t%s\n", n, line) } } } :Ctrl + Z然后在Windows中输入,或在Linux中输入Ctrl + D.

选项B:将所有文本数据保存在一个文件中,如" lines.txt"然后使用此文件作为输入(Redirecting input)运行您的go二进制文件,如下所示:

Windows:

EOF

Linux:

main.exe < lines.txt

答案 2 :(得分:0)

你出错的地方是:

您没有给第一个 for 循环终止任何条件。这将为您提供Volker建议的两个选项。无论哪种方式,您实际上都在为程序提供 EOF ,以便知道何时停止扫描输入。

现在,这对你来说可能看起来不太干净。在这种情况下(仅在这种情况下),您可以继续在输入的输入中引入终止条件:

if input.Text() == "" {
    break;
}

一旦输入两个换行符,这将导致执行到达第二个 for 循环。如果您想在程序开头提示用户点击两次以显示结果,或者其他类似的东西,那就太方便了。

干杯!