服务计算 3 | 用 golang 开发 selpg

用 golang 开发 selpg

一、代码连接

github 连接

二、Selpg相关内容

selpg 是从文本输入选择也范围的实用程序。该输入可以来自作为最后一个命令行参数指定的文件,在没有给出文件名参数时也可以来自标准输入

selpg首先要处理所有的命令行参数,在扫描了所有的选项参数(也就是哪些以连字符为前缀的参数后,如果 selpg 还发现有一个参数,则将其作为输入文件的名称并尝试打开它进行读取,如果没有其他参数,则 selpg 假定输入来自标准输入

selpg 的 C 语言代码

因此这份代码基本参考上面那份C语言代码

三、参数设置

  1. 输入格式

    selpg [-s 开始读取页号][-e 结束读取页号][-l 一页多少行 | -f ][-d 输出目的地] 文件名

  2. 必要的参数

    -s 后接开始读取的页号(int)

    -e 后接结束读取的页号(int)

  3. 可选的参数

    -l 后接行数(int),代表多少行一页,默认72行

    -f 表示分页

四、具体代码

1. 引用包

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"os/exec"
	"strings"

	flag "github.com/ogier/pflag"
)

2. 数据结构

和 C 语言代码一样,建了一个结构体

type selpgArgs struct {
	start_page  int
	end_page    int
	page_len    int
	page_type   bool
	print_dest  string
	in_filename string
}

3. main函数

C语言代码里面,main函数设置了各个参数的初始值,在函数 process_args() 里面处理输入,go语言可以通过 flag 来处理输入。

flag.IntVarP(&sa.start_page, "s", "s", -1, "the start page")
flag.IntVarP(&sa.end_page, "e", "e", -1, "the end page")
flag.IntVarP(&sa.page_len, "l", "l", 72, "the paging form")
flag.StringVarP(&sa.print_dest, "d", "d", "", "the printer")
flag.BoolVarP(&sa.page_type, "f", "f", false, "is read by page")

同时由输入格式可以看出,还有一个不带参数的输入是文件名,这个要自行读取存储

if flag.NArg() == 1 {
	sa.in_filename = flag.Arg(0)
} else {
	sa.in_filename = ""
}

然后就是一个检验输入的函数 handle_args() 和一个执行的函数process_input()

4.handle_args()

第一部分是处理 C 语言代码里面是否存在初始页数大于终止页数,及分别小于1的情况的

if sa.start_page > sa.end_page || sa.start_page < 1 {
	usage()
	os.Exit(1)
}

第二部分是处理是否有过多的非参数指令的

if notFlagNum != 1 && notFlagNum != 0 {
	usage()
	os.Exit(1)
}

第三部分是处理是否出现 -f -l xxx 的情况的

if sa.page_type == true {
	if sa.page_len != -1 {
		usage()
		os.Exit(1)
	}
}

这里面调用的usage()函数是输出应该输入的格式,格式在上面有给出

5.process_input()

这里和C语言代码一样,首先处理输入来源

//set the input source
if sa.in_filename != "" {
	fin, err = os.Open(sa.in_filename)
	if err != nil {
		fmt.Fprintf(os.Stderr, "selpg: could not open input file \"%s\"\n", sa.in_filename)
		fmt.Println(err)
		usage()
		os.Exit(1)
	}
	defer fin.Close()
}

然后处理输出,这里参考了别人的博客

//set the output
fout := os.Stdout
var inpipe io.WriteCloser
if sa.print_dest != "" {
	cmd := exec.Command("lp", "-d"+sa.print_dest)
	inpipe, err = cmd.StdinPipe()
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	defer inpipe.Close()
	cmd.Stdout = fout
	cmd.Start()
}

然后分别处理按行读取和按页读取,关于这部分参考了博客:Go如何按行读取文件及bufio.Split()函数的使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值