zoukankan      html  css  js  c++  java
  • Golang: 读取文件并统计内容

    上次我们从命令行接收用户输入,并统计了每次输入内容出现的次数,今天对程序加以改造,使其能够读取文件内容,并统计每行文本出现的次数。

    首先,我们把接收输入的逻辑封装成一个函数:

    // scan.go
    
    package main
    
    import (
        "os"
        "fmt"
        "bufio"
    )
    
    func main() {
        counts := make(map[string]int)
    
        fmt.Printf("Please type in something:
    ")
    
        countLines(os.Stdin, counts)
    
        for line, n := range counts {
            fmt.Printf("%d : %s
    ", n, line)
        }
    }
    
    // 统计行数
    func countLines(file *os.File, counts map[string]int) {
        input := bufio.NewScanner(file)
    
        for input.Scan() {
            line := input.Text()
    
            if line == "bye" {
                break
            }
    
            counts[line]++
        }
    }
    

    上面的 coutLines() 函数有两个参数:file *os.File 和 counts map[string]int,第一个参数可以接收标准输入或文件对象,第二个参数接收一个 map 引用。

    然后,我们移除接收命令行输入的逻辑,替换为读取当前目录下的 test.txt 文件:

    // scan.go
    
    package main
    
    import (
        "os"
        "fmt"
        "bufio"
    )
    
    func main() {
        counts := make(map[string]int)
    
        // 打开文件
        file, err := os.Open("test.txt")
    
        // 异常处理
        if err != nil {
            fmt.Fprintf(os.Stderr, "%v
    ", err)
            return
        }
    
        countLines(file, counts)
    
        // 关闭文件
        file.Close()
    
        for line, n := range counts {
            fmt.Printf("%d : %s
    ", n, line)
        }
    }
    
    // 统计行数
    func countLines(file *os.File, counts map[string]int) {
        input := bufio.NewScanner(file)
    
        for input.Scan() {
            counts[input.Text()]++
        }
    }
    

    我们使用 os.Open 打开 test.txt 文件,如果出现异常,则进行异常处理,如果读取成功,则统计内容,最后关闭文件。

    test.txt 文件内容如下:

    hello
    world
    hello
    

    下面是程序的运行结果:

    $ go run scan.go
    # 输出内容
    2 : hello
    1 : world
    

    除上述方式之外,我们还可以使用 io/ioutil 中的方法来读取文件,然后以换行符分割进行统计,实现代码如下:

    // split.go
    
    package main
    
    import (
        "os"
        "fmt"
        "strings"
        "io/ioutil"
    )
    
    func main() {
        counts := make(map[string]int)
    
        // 读取文件
        data, err := ioutil.ReadFile("test.txt")
    
        // 异常处理
        if err != nil {
            fmt.Fprintf(os.Stderr, "%v
    ", err)
            return
        }
    
        // 将数据转换为字符串 然后以换行符分割
        lines := strings.Split(string(data), "
    ")
    
        for _, line := range lines {
            counts[line]++
        }
    
        for line, n := range counts {
            fmt.Printf("%d : %s
    ", n, line)
        }
    }
    
  • 相关阅读:
    BZOJ 3811: 玛里苟斯 线性基
    HDU 3949 XOR 线性基
    BZOJ 2115: [Wc2011] Xor 线性基 dfs
    BZOJ 3963 HDU3842 [WF2011]MachineWorks cdq分治 斜率优化 dp
    BZOJ 3262: 陌上花开 cdq分治 树状数组
    BZOJ 2653: middle 主席树 二分
    BZOJ 3524 [Poi2014]Couriers 主席树
    BZOJ 4826: [Hnoi2017]影魔 单调栈 主席树
    BZOJ 3956: Count 主席树 可持久化线段树 单调栈
    2018/4/9省选模拟赛 0分
  • 原文地址:https://www.cnblogs.com/liuhe688/p/9597741.html
Copyright © 2011-2022 走看看