Golang编程语言示例解析:ch1/dup2控制台与文件行为对比
Golang编程语言示例解析:ch1/dup2控制台与文件行为对比 大家好,
我是Go语言的新手,正在学习《Go程序设计语言》这本书,第一章的示例程序dup2。我创建了一个测试文件test.txt,内容如下:
harry
ron
hermione
ron
hagrid
dumbledore
harry
sneep
hermione
运行main.exe test.txt得到了预期的输出:
2 harry
2 ron
2 hermione
但是运行main.exe,通过键盘输入上述内容并以ctrl+c结束时,通常会漏掉一个条目(多次运行时漏掉的条目不一致)。可能的输出:
2 ron
2 hermione
或者
2 harry
2 ron
这是预期的行为吗?(我在Windows 10系统上运行,安装了go1.11.4版本。)
感谢帮助。
更多关于Golang编程语言示例解析:ch1/dup2控制台与文件行为对比的实战教程也可以访问 https://www.itying.com/category-94-b0.html
你好,能给我们看看这个程序吗?
更多关于Golang编程语言示例解析:ch1/dup2控制台与文件行为对比的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
《Go程序设计语言》的第一章可在线获取:http://www.gopl.io/ch1.pdf
dup2的代码印在第10页及后续页面。
你好Norbert,
这个:
NobbZ: 据我所知,Windows系统中相当于<kbd>Ctrl</kbd>-<kbd>D</kbd>的组合键是<kbd>Ctrl</kbd>-<kbd>Z</kbd>。
回答了我的问题,谢谢!
就我个人而言,如果运行这本书中链接的程序并使用<kbd>Ctrl</kbd>-<kbd>C</kbd>终止,我完全看不到任何后续输出。程序直接被取消,说实话,我认为在Windows系统上也会出现同样的情况。
但如果使用<kbd>Ctrl</kbd>-<kbd>D</kbd>(在Linux系统中用于发送EOF),每次都能看到正确的输出。
根据我的记忆,Windows系统中与<kbd>Ctrl</kbd>-<kbd>D</kbd>等效的操作是<kbd>Ctrl</kbd>-<kbd>Z</kbd>。
在Go语言中,dup2示例程序的行为差异是预期的,主要源于控制台输入和文件输入的处理方式不同。当从文件读取时,程序可以完整扫描整个内容;而从控制台输入时,依赖用户手动结束输入(如按Ctrl+C),这可能导致缓冲数据未完全处理。
以下是dup2的典型实现代码,基于《Go程序设计语言》第一章:
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
counts := make(map[string]int)
files := os.Args[1:]
if len(files) == 0 {
countLines(os.Stdin, counts)
} else {
for _, arg := range files {
f, err := os.Open(arg)
if err != nil {
fmt.Fprintf(os.Stderr, "dup2: %v\n", err)
continue
}
countLines(f, counts)
f.Close()
}
}
for line, n := range counts {
if n > 1 {
fmt.Printf("%d\t%s\n", n, line)
}
}
}
func countLines(f *os.File, counts map[string]int) {
input := bufio.NewScanner(f)
for input.Scan() {
counts[input.Text()]++
}
// 注意:忽略input.Err()可能的错误
}
行为分析:
- 文件输入:程序读取整个文件,所有行被完整计数,输出所有重复行(如
harry、ron、hermione各出现2次)。 - 控制台输入:当通过键盘输入并以
Ctrl+C结束时,这是一个中断信号(SIGINT)。在Windows系统中,这可能导致缓冲的输入数据未被bufio.Scanner完全读取,因为扫描器可能在中断时尚未处理最后一行。例如,如果输入序列是:
扫描器可能只捕获到部分行,取决于中断时机,从而漏掉harry ron hermione ron [Ctrl+C]harry或hermione。
示例重现控制台问题: 在控制台运行程序并输入:
harry
ron
hermione
ron
hagrid
dumbledore
harry
sneep
hermione
[Ctrl+C]
输出可能缺少一个条目,因为Ctrl+C立即终止进程,缓冲中的数据可能丢失。
总结: 这是预期行为,与控制台输入缓冲和中断处理相关。在类Unix系统(如Linux或macOS)上,行为可能类似,但Windows的终端处理略有差异。建议使用文件输入进行可靠测试,或通过标准输入重定向(如main.exe < test.txt)来模拟文件输入。

