处理输入的简单程序都有一个差不多的设计结构:一个处理输入的循环,在每个元素上执行计算处理,在处理的同时或最后产生输出。
stdin
// Dup prints the text of each line that appears more than
// once in the standard input, preceded by its count.
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
//分行读取标准输入s,将s放入map统计出现次数
input := bufio.NewScanner(os.Stdin)
statistic := make(map[string]int)
for input.Scan() {
line := input.Text()
statistic[line]++
}
//打印出现重复的输入
for line, num := range statistic {
if num > 1 {
fmt.Printf("%s\t%d\n", line, num)
}
}
}
复制代码
input := bufio.NewScanner(os.Stdin)os.StdinFILEbufioScannerinput.Scan()input.Text()
statistic := make(map[string]int)mapmapkey/value==makemapmake
示例代码(以文件作为输入):
// Dup2 prints the count and text of lines that appear more than once
// in the input. It reads from stdin file
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
//读取文件名
var file string
if len(os.Args) != 2 {
fmt.Fprintln(os.Stderr, "Paramater number error!")
return
} else {
file = os.Args[1]
}
//打开文件
f, err := os.Open(file)
if err != nil {
fmt.Fprintf(os.Stderr, "open file error: %v\n", err)
return
}
//分行读取文件,将内容放入map统计出现次数
input := bufio.NewScanner(f)
statistic := make(map[string]int)
for input.Scan() {
line := input.Text()
statistic[line]++
}
f.Close()
//打印出现重复的输入
for line, num := range statistic {
if num > 1 {
fmt.Printf("%s\t%d\n", line, num)
}
}
}
复制代码
os.Open*os.FileScanner
os.OpenerrorerrnilCloseerrnilFprintf
Go中错误处理在所有的高级语言中简直是一股清流啊,这其实贴合Go的开发思想,简单、直观。事实上,我们在设计代码逻辑的时候,本来就是在考虑两种情况,成功了往下走,失败了怎么办?我们在开发产品的时候,本质上在不断取舍,在可能出现错误的地方用分支语句处理就可以了,既符合逻辑又直白简单。
以上两种读取输入的方式都是使用的“流”模式,并根据需要拆分成多个行。理论上,这些程序可以处理任意数量的输入数据。还有另一个方法,就是一口气把全部输入数据读到内存中,一次分割为多行,然后处理它们。
示例代码(以文件作为输入):
package main
import (
"fmt"
"io/ioutil"
"os"
"strings"
)
func main() {
//读取文件名
var file string
if len(os.Args) != 2 {
fmt.Fprintln(os.Stderr, "Paramater number error!")
return
} else {
file = os.Args[1]
}
//读取文件所有内容
data, err := ioutil.ReadFile(file)
if err != nil {
fmt.Fprintf(os.Stderr, "open file error: %v\n", err)
return
}
//分行统计数据
content := string(data)
statistic := make(map[string]int)
for _, line := range strings.Split(content, "\r\n") {
statistic[line]++
}
//打印出现重复的输入
for line, num := range statistic {
if num > 1 {
fmt.Printf("%s\t%d\n", line, num)
}
}
}
复制代码
ReadFilebyte slicestringstrings.Splitbufio.Scannerioutil.ReadFile ioutil.WriteFIle*os.FileReadWritebufioio/ioutil