使用Go语言实现Selpg

本文介绍了一个使用Go语言实现的selpg工具,该工具可以按自定义方式分页显示文件内容,支持行分割和页分割,同时能够处理开始页和结束页的参数,确保输出范围正确。文章详细解释了代码结构、输入输出处理以及错误检查机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


selpg本质上就是将一个文件,通过自己设定的分页方式,输出到屏幕或者重定向到其他文件上,或者利用打印机打印出来。根据selpg的c代码,使用go语言实现。

大致实现如下:

引用的包
值得一提的是需要用到 go 封装的 pflag 包,能够方便地解析参数。

import (
	"fmt"	
	"strings"
	"errors"
	"bufio"
	"io"
	"bytes"
	"os"
	"os/exec"
	flag "github.com/spf13/pflag"
	)

变量初始化
这里进行了五个变量的声明和初始化,各个变量的含义如下解释。接下来的就是一些关于报错输入输出流的绑定、读入数据变量创建等。此外,要使用flag.Parse()解析上面初始化的变量。

var start_page = flag.Int("s", -1, "The start page")
var end_page = flag.Int("e", -1, "The end page")
var line_delim = flag.Bool("l", true, "Delimeter")
var page_len = flag.Int("p", 72, "The legnth of a page")
var print_dest = flag.String("d", "none", "Destination ")

var in_filename string
var err error

const inbuff_size = 16*1024

处理错误信息
发生错误时,终端发出提醒,并结束程序。

func usage(err error) {
	if err != nil {
		fmt.Printf("Error \n\n", err)
		os.Exit(1)
	}
}

主函数
根据程序的功能,按流程调用不同的方法即可。具体可参考c语言实现。

func main() {
    flag.Parse()

    err = process_args()
    usage(err)

    str, err := process_input()
    usage(err)
    fmt.Println(str)

    fmt.Printf("Finish printing")
}

检查输入参数
对输入的参数,需要检查它们的合法性。比如有无输入、开始页是否小于等于结束页等等,需要考虑到各种情况。

func process_args() error {
	if *start_page == -1 || *end_page == -1 {
		return errors.New("Page arguments' wrong \n")
	}

	if *start_page <= 0 || *start_page > (inbuff_size-1) {
		return errors.New("Invalid start page \n")
	}		

	if *end_page <= 0 || *end_page > (inbuff_size-1) {
		return errors.New("Invalid end page \n")
	}

	if *start_page > *end_page {
		return errors.New("Invalid page range \n")
	}

	if *line_delim == true && *page_len == 72 {//又是行分割又是也分割 
		return errors.New("Enter command either -l or -f \n")
	}

	return nil
}

输入输出
输入的方式有两种,一种是标准输入的模式,一种是文件输入的方式。

对于文件输入的模式来说,需要有一个文件参数,使用os.Open()打开文件,然后就通过file.Read()迭代的读出所有的文件内容。而标准输入没有文件参数。

func process_input() (string, error) {
	result := ""
	page := 1 
	line := 0
	reader := bufio.NewReader(os.Stdin)

	// 如果有文件参数的话
	if flag.NArg() > 0 {
		in_filename = flag.Arg(0)
		file , err := os.Open(in_filename)
		if err != nil {
			return "", err
		}

		defer file.Close()
		reader = bufio.NewReader(file)
	}

	if *line_delim {
		// 行分割
		page = 1
		line = 0

		for {
			str, err := reader.ReadString('\n')
			if err == io.EOF {
				break
			} else if err != nil {
				return "", err
			}

			line++
			if line > *page_len {
				page++
				line = 1
			}
			if page >= *start_page && page <= *end_page {
				result = strings.Join([]string{result, str}, "")
			}
		}
		
	} else {
		// 页分割
		page = 1

		for {
			str, err := reader.ReadString('\f')
			if err == io.EOF {
				break
			} else if err != nil {
				return "", err
			}

			page++
			if page >= *start_page && page <= *end_page {
				result = strings.Join([]string{result, str}, "")
			}
		}
	}

	// 检查起始、结束页是否正确
	if page < *start_page {
		msg := fmt.Sprintf("Start page is out of the range")
		return "", errors.New(msg)
	} else if page > *end_page {
		msg := fmt.Sprintf("End page is out of the range")
		return "", errors.New(msg)
	}

	//
	if *print_dest != "none" {
		cmd := exec.Command("lp", "-d" + *print_dest)
		cmd.Stdin = strings.NewReader(result)
		var stderr bytes.Buffer
		cmd.Stderr = &stderr
		err = cmd.Run()
		if err != nil {
			return "", errors.New(fmt.Sprint(err) + ":" + stderr.String())
		}
	}

	return result, nil
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值