服务计算:GO语言编写简单的CLI

这次作业使用GO语言编写一个在linux下运行的简单的CLI程序
这是我本次作业实现的selpg.go项目

1. 设计思路

这个selpg的CLI实现的思路很简单:
(1)读取命令并解析对应的参数,初始化程序运行的变量和参数
(2)读入目标文件(通过重定向的方式或手动输入的方式)
(3)根据预设的参数对文件执行读写操作
(4)将对应输出输出到相应的文件中

2. 代码分析

(1)参数解析部分
// 使用pflag进行参数的定义
flag.IntVarP(&s, "s", "s", 1, "start page")
flag.IntVarP(&e, "e", "e", 1, "end page(e >= s)")
flag.IntVarP(&lines, "l", "l", 72, "page length")
flag.BoolVarP(&changeLine, "f", "f", false, "change page by symbol '\\f'")
flag.Lookup("f").NoOptDefVal = "true"
flag.StringVarP(&pipe, "d", "d", "", "printer")
flag.Usage = func() {
    fmt.Fprintln(os.Stderr, "Format: ./selpg [-s n] [-e n] [-f | -l n] [-d p] [filename] [other options]")
    flag.PrintDefaults()
}

flag.Parse()

// 判断输入是文件重定向还是用户自主输入
if flag.NArg() == 1 {
    _, file_err := os.Stat(flag.Args()[0])
    if file_err != nil {
        return file_err
    }
    input_file = flag.Args()[0]
} else if flag.NArg() > 1 {
    flag.Usage()
    err = errors.New("ERROR: too many args")
}
(2)文件读写部分

利用os.Open和bufio读取文件内容部分

f, err := os.Open(filename)
if filename == "" {
    f = os.Stdin
} else {
    if err != nil {
        fmt.Fprintln(os.Stderr, err)
    }
}
defer f.Close()
buf := bufio.NewReader(f)

处理以行数作为换页标志的情况

for page = 1; page <= e; page += 1 {
    count = 1
    for {
        if count > lines {
            break
        }
        line, err := buf.ReadString('\n')
        count += 1
        if page < s {
            if err != nil {
                return err
            } else {
                continue
            }
        }
        // 输出
        if err == nil {
            out.Write([]byte(line))
        } else if err == io.EOF {
            out.Write([]byte(line))
        } else {
            return err
        }
    }

处理以换页符作为换页标志的情况

page = 0
for page < e {
    line, err := buf.ReadString('\f')
    page += 1
    if page < s {
        if err != nil {
            return err
        } else {
            continue
        }
    }
    // 输出
    if err == nil {
        out.Write([]byte(line))
    } else if err == io.EOF {
        out.Write([]byte(line))
    } else {
        return err
    }
}
(3)main函数
// 获取并处理参数
err = getArgs()
if err == nil {
	// 输出位置
    out = os.Stdout
    // 假如打印机选项不为空,则执行sendToPrinter()
    // 否则,直接读取文件并按照用户要求输出
    if pipe != "" {
        sendToPrinter()
    } else {
        err = readFile(input_file)
    }
}

3. 测试结果

测试数据为test.txt

(1)以默认方式读取用户输入的文件(按72行为一页)

在这里插入图片描述

(2)以默认方式读取重定向文件(按72行为一页)

在这里插入图片描述

(3)以默认方式读取用户输入的文件(按4行为一页)

在这里插入图片描述

(4)以分页符方式读取用户输入的文件(分页符为一页)

在这里插入图片描述

(5)将读入的文件内容发送到打印机

在这里插入图片描述

(6)将cat命令的进程的输出作为selpg命令的进程的输入

在这里插入图片描述

(7)将selpg命令的进程的输出作为cat命令的进程的输入

在这里插入图片描述

(8)将输出重定向至output.txt文件

在这里插入图片描述

在这里插入图片描述

(9)将错误输出重定向至error.txt文件

在这里插入图片描述
在这里插入图片描述

(10)错误提示

1.文件出错
在这里插入图片描述
2.页码错误(如:开始页大于结束页)
在这里插入图片描述
3.参数错误(如:格式错误)
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZTao-z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值