Go程序设计语言练习题-第7章

7.1:使用类似ByteCounter的想法,实现单词和行的计数器,实现时考虑使用bufio.ScanWords。

package main

import (
    "bufio"
    "fmt"
)

type WordsCounter int

func (c *WordsCounter) Write(content []byte) (int, error) {
    for start := 0; start < len(content); {
        //跳过开头的space,返回遇到第一个word后下次scan的开始index
        //Hello Worlds 调用bufio.ScanWords返回
        //6 [Hello的字节slice] nil
        advance, _, err := bufio.ScanWords(content[start:], true)
        if err != nil {
            return 0, err
        }
        start += advance
        (*c)++
    }
    return int(*c), nil
}

type LinesCounter int

func (c *LinesCounter) Write(content []byte) (int, error) {
    for start := 0; start < len(content); {
        advance, _, err := bufio.ScanLines(content[start:], true)
        if err != nil {
            return 0, err
        }
        start += advance
        (*c)++
    }
    return int(*c), nil
}

func main() {
    var wc WordsCounter
    wc.Write([]byte("Hello Worlds Test Me"))
    fmt.Println(wc) // 4
    wc.Write([]byte("append something to the end"))
    fmt.Println(wc) // 9

    var lc LinesCounter
    fmt.Fprintf(&lc, "%s\n%s\n%s\n", "Hello World", "Second Line", "Third Line")
    fmt.Println(lc) // 3
    fmt.Fprintf(&lc, "%s\n%s\n%s", "第4行", "第5行", "")
    fmt.Println(lc) // 5
}
View Code

7.2:实现一个满足如下签名的CountingWriter函数,输入一个io.Writer,输出一个封装了输入值的心Writer,以及一个置项int64的指针,改制真对应的值是新的Writer吸入的字节数。

package main

import (
    "fmt"
    "io"
    "os"
)

type CountWriter struct {
    Writer io.Writer
    Count  int
}

func (cw *CountWriter) Write(content []byte) (int, error) {
    n, err := cw.Writer.Write(content)
    if err != nil {
        return n, err
    }
    cw.Count += n
    return n, nil
}

func CountingWriter(writer io.Writer) (io.Writer, *int) {
    cw := CountWriter{
        Writer: writer,
    }
    return &cw, &(cw.Count)
}

func main() {
    cw, counter := CountingWriter(os.Stdout)
    fmt.Fprintf(cw, "%s", "Print somethind to the screen...")
    fmt.Println(*counter)
    cw.Write([]byte("Append soething..."))
    fmt.Println(*counter)
}
View Code

7.5:io包中的LimitReader函数接受一个io.Reader r和字节数n,返回一个Reader,该返回值从r读取数据,但在读取n字节后报告文件结束,请实现该函数。

func LimitReader(r io.Reader,n int64) io.Reader

package main

import (
    "fmt"
    "io"
    "os"
)

type LimitedReader struct {
    Reader  io.Reader
    Limit   int
    current int
}

func (r *LimitedReader) Read(b []byte) (int, error) {
    if r.current >= r.Limit {
        return 0, io.EOF
    }

    if r.current+len(b) > r.Limit {
        b = b[:r.Limit-r.current]
    }
    n, err := r.Reader.Read(b)
    if err != nil {
        return n, err
    }
    r.current += n
    return n, nil
}

func LimitReader(r io.Reader, limit int) io.Reader {
    lr := LimitedReader{
        Reader: r,
        Limit:  limit,
    }
    return &lr
}

func main() {
    file, err := os.Open("limit.txt") // 1234567890
    if err != nil {
        panic(err)
    }
    defer file.Close()

    lr := LimitReader(file, 5)
    buf := make([]byte, 10)
    n, err := lr.Read(buf)
    if err != nil {
        panic(err)
    }
    fmt.Println(n, buf) // 5 [49 50 51 52 53 0 0 0 0 0]
}
View Code

猜你喜欢

转载自www.cnblogs.com/ling-diary/p/10294916.html