從標準輸入讀取文本,統計相同文本出現的次數
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 變量的類型
%% 字面上的百分號標誌(無操作數)