从标准输入读取文本,统计相同文本出现的次数
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
// 统计文本 {"文本1":5 } 即`文本1`出现5次
counts := make(map[string]int)
// os.Stdin 是标准输入, 就是屏幕终端输入的信息
// bufio.NewScanner 创建并返回从 `标准输入中` 读取数据的Scanner
// Scanner 类型是什么呢?提供了方便的读取数据的接口,如从换行符分隔的文本里读取每一行
input := bufio.NewScanner(os.Stdin)
// 调用Scanner.Scan()返回的是true/false
// 他判断的是 是否有输入, ctrl+D 则返回false,他是阻塞的
// 当它执行后,调用input.Text() 就可以获取到值,
// 如果连续执行两次Scanner.Scan(),则第一次的值就会被跳过
// 文档中有个token的概念,它就是让Scanner的扫描位置移动到下一个token,
// 如果你不使用Bytes或Text方法获得值,则会错过。
for input.Scan() {
// 不用担心没有 ,我们设置的int类型 ,默认没有初始值为0
counts[input.Text()]++
}
// ctrl+D 后上面的for循环会终止(不满足循环条件)
// 遍历map key:value
for line, n := range counts {
if n >= 1 {
fmt.Print(line,,n)
}
}
}
go run find.go
没有参数,则从标准输入中读取数据
go run find.go 1.txt 2.txt ...
有参数,则从对应的文件中读取数据
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 {
// os.Open打开文件
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()]++
}
}
只读文件 不读标准输入,换一个方法读取文件
io/ioutil
package main
import (
"fmt"
"io/ioutil"
"os"
"strings"
)
func main() {
counts := make(map[string]int)
for _, filename := range os.Args[1:] {
// data 是 字节切片(byte slice)
data, err := ioutil.ReadFile(filename)
if err != nil {
fmt.Fprintf(os.Stderr, "dup3: %v\n", err)
continue
}
// 把切片转成string, 使用Split分割,
// 这里最后一个元素为"" 因为最后一个是换行符,所以比预期的多一个""
for _, line := range strings.Split(string(data), "\n") {
counts[line]++
}
}
for line, n := range counts {
if n >= 1 {
fmt.Printf("%d\t%s\n", n, line)
}
}
}
补充printf
%d 十进制整数
%x, %o, %b 十六进制,八进制,二进制整数。
%f, %g, %e 浮点数: 3.141593 3.141592653589793 3.141593e+00
%t 布尔:true或false
%c 字符(rune) (Unicode码点)
%s 字符串
%q 带双引号的字符串"abc"或带单引号的字符'c'
%v 变量的自然形式(natural format)
%T 变量的类型
%% 字面上的百分号标志(无操作数)