服务计算第三次作业selpg

先上测试结果:

    sa.page_len = 3;

    将一页长度定义为3行

    测试文件test.txt如下:

  命令一:go run selpg.go -s1 -e1 test.txt

 

  命令二:go run selpg.go -s1 -e1 < test.txt

 

  命令三:java -version | go run selpg.go -s1 -e1

  命令四:go run selpg.go -s1 -e2 test.txt >test4.txt

 

  命令五:go run selpg.go -s1 -e2 test.txt 2>error5.txt

shell输出

error5.txt文件

  命令六:go run selpg.go -s1 -e2 test.txt >test6.txt 2>error6.txt

输出到detext6.txt的文件
此处输入图片的描述
错误信息

  命令七:go run selpg.go -s1 -e2 test.txt >test7.txt 2>/dev/null

保留输出信息,舍弃错误信息

  命令八:go run selpg.go -s1 -e2 test.txt > /dev/null

输出信息舍弃

  命令九:go run selpg.go -s1 -e2 test.txt | cat

selpg程序的标准输出定位到cat的标准输入。

  命令十:go run selpg.go -s1 -e2 test.txt 2>error10.txt | cat

输出结果同命令九

  命令十一:go run selpg.go -s1 -e2 -l66 test.txt

一页的长度改变了,所以输出全部

  命令十二:go run selpg.go -s1 -e2 -f test.txt

  命令十三:go run selpg.go -s1 -e2 -dlp1 test.txt

 

  命令十四:go run selpg.go -s1 -e2 test.txt > test14.txt 2>error14 &

 

根据教程里给的c语言文件转换为go语言文件。 由于这两种不同的语言的语法也是不一样的,并不能直接转换。

简略给出设计的步骤:

1.首先要导入所需要的包

import (

"fmt"

"os"

"strings"

"strconv"

"bufio"

"io"

"os/exec"

)

2.定义结构提体

type selpg_args struct {

start_page int

end_page int

in_filename string

  page_len int

  page_type int

print_dest string

}

3.函数接口,语法转换:两者相似的地方,也有很多相异。整体来说转换过程不算困难。 方法接口转换:两者包和库有多个相似功能,但转换过程比较困难,原因在于未能熟练使用语言的包。经过在百度和官方文档 中的查阅,最终得以解决。

代码具体:

package main

import (

"fmt"

"os"

"strings"

"strconv"

"bufio"

"io"

"os/exec"

)

type selpg_args struct {

start_page int

end_page int

in_filename string

  page_len int

  page_type int

print_dest string

}

type sp_args selpg_args

var progname string

const DEBUG bool = true

const INT_MAX int = (1 << 31) - 1

func main() {

for i, a := range os.Args[1:] {

fmt.Printf("Argument %d is %s\n", i+1, a)

}

var sa selpg_args

  progname = os.Args[0]

  sa.start_page = -1

sa.end_page = -1

  sa.in_filename = ""

  sa.page_len = 72;

  sa.page_type = 'l'

  sa.print_dest = ""

  process_args(len(os.Args), os.Args, &sa)

  process_input(sa)

}

func process_args(ac int, av []string, psa *selpg_args) {

var s1 string /* temp str */

var s2 string /* temp str */

  var argno int /* arg # currently being processed */

  /* arg at index 0 is the command name itself (selpg),

   first actual arg is at index 1,

   last arg is at index (ac - 1) */

var i int

  /* check the command-line arguments for validity */

  if (ac < 3) {

fmt.Fprintf(os.Stderr, "%s: not enough arguments\n", progname)

    usage();

    os.Exit(1)

  }

if (DEBUG) {

fmt.Fprintf(os.Stderr, "DEBUG: before handling 1st arg\n")

}

s1 = av[1]

var substr1 = s1[0:2]

if (!strings.EqualFold(substr1, "-s")) {

fmt.Fprintf(os.Stderr, "%s: 1st arg should be -sstart_page\n", progname)

usage();

    os.Exit(2)

}

i, _ = strconv.Atoi(s1[2:len(s1)])

if ( i < 1 || i > (INT_MAX - 1) ) {

fmt.Fprintf(os.Stderr, "%s: invalid start page %s\n", progname, s1[2:len(s1)])

    usage()

    os.Exit(3)

  }

psa.start_page = i

if (DEBUG) {

fmt.Fprintf(os.Stderr, "DEBUG: before handling 2nd arg\n")

}

s1 = av[2]

substr1 = s1[0:2]

if (!strings.EqualFold(substr1, "-e")) {

fmt.Fprintf(os.Stderr, "%s: 2nd arg should be -eend_page\n", progname)

usage();

    os.Exit(4)

}

i, _ = strconv.Atoi(s1[2:len(s1)])

if ( (i < 1) || (i > (INT_MAX - 1)) || (i < psa.start_page) ) {

fmt.Fprintf(os.Stderr, "%s: invalid end page %s\n", progname, s1[2:len(s1)])

    usage();

    os.Exit(5)

  }

psa.end_page = i

if (DEBUG) {

fmt.Fprintf(os.Stderr, "DEBUG: before while loop for opt args\n")

}

argno = 3;

for (argno <= (ac - 1) && av[argno][0] == '-') {

s1 = av[argno]

switch(s1[1]) {

case 'l':

s2 = s1[2:len(s1)]

i, _ = strconv.Atoi(s2)

if ( i < 1 || i > (INT_MAX - 1) ) {

fmt.Fprintf(os.Stderr, "%s: invalid page length %s\n", progname, s2)

usage()

os.Exit(6)

}

psa.page_len = i

argno++

continue

break /* break after continue not reqd, defensive prog. */

case 'f':

/* check if just "-f" or something more */

if (!strings.EqualFold(s1, "-f")) {

fmt.Fprintf(os.Stderr, "%s: option should be \"-f\"\n", progname)

usage()

os.Exit(7)

}

psa.page_type = 'f'

argno++

continue

break

case 'd':

s2 = s1[2:len(s1)]

if (len(s2) < 1) {

fmt.Fprintf(os.Stderr,

"%s: -d option requires a printer destination\n", progname)

usage()

os.Exit(8)

}

psa.print_dest = s2

argno++

continue

break

default:

fmt.Fprintf(os.Stderr,

"%s: unknown option %s\n", progname, s1)

usage()

os.Exit(9)

break

} /* end switch */

}

if (DEBUG) {

fmt.Fprintf(os.Stderr, "DEBUG: before check for filename arg\n")

fmt.Fprintf(os.Stderr, "DEBUG: argno = %d\n", argno)

}

if (argno <= (ac - 1)) {

psa.in_filename = av[argno]

    /* check if file exists */

fi, err := os.Stat(psa.in_filename)

    if (err != nil) {

fmt.Fprintf(os.Stderr, "%s: input file \"%s\" does not exist\n",

progname, psa.in_filename)

      os.Exit(10)

    }

    /* check if file is readable */

    if ((fi.Mode() & os.ModePerm & 0x4) == 0) {

fmt.Fprintf(os.Stderr, "%s: input file \"%s\" exists but cannot be read\n",

      progname, psa.in_filename)

      os.Exit(11)

    }

  }

if (psa.start_page <= 0) {

os.Exit(112)

}

if (!(psa.end_page > 0 && psa.end_page >= psa.start_page)) {

os.Exit(113)

}

if (psa.page_len <= 1) {

os.Exit(114)

}

if (!(psa.page_type == 'l' || psa.page_type == 'f')) {

os.Exit(115)

}

if (DEBUG) {

fmt.Fprintf(os.Stderr, "DEBUG: psa->start_page = %d\n", psa.start_page)

fmt.Fprintf(os.Stderr, "DEBUG: psa->end_page = %d\n", psa.end_page)

fmt.Fprintf(os.Stderr, "DEBUG: psa->page_len = %d\n", psa.page_len)

fmt.Fprintf(os.Stderr, "DEBUG: psa->page_type = %c\n", psa.page_type)

fmt.Fprintf(os.Stderr, "DEBUG: psa->print_dest = %s\n", psa.print_dest)

fmt.Fprintf(os.Stderr, "DEBUG: psa->in_filename = %s\n", psa.in_filename)

}


 

}

/*================================= process_input() ===============*/

func process_input(sa selpg_args) {

  var fin *os.File

  //var fout *os.File

  var s1 string

  //var crc string

//var c int

  //var line string

var line_ctr int

  var page_ctr int

var wc io.Writer

var err error

var cmd *exec.Cmd

  /* set the input source */

  if (len(sa.in_filename) == 0) {

    fin = os.Stdin

  } else {

    fin, err = os.OpenFile(sa.in_filename, os.O_RDONLY, 0666)

    if (err != nil) {

fmt.Fprintf(os.Stderr, "%s: could not open input file \"%s\"\n",

      progname, sa.in_filename)

os.Exit(12)

    }

  }

  /* use setvbuf() to set a big buffer for fin, for performance */

inbuf := bufio.NewReader(fin)

  /* set the output destination */

  if (len(sa.print_dest) == 0) {

    //fout = os.Stdout

// wc = bufio.NewWriter(os.Stdout)

  } else {

    (os.Stdout).Sync()

fmt.Sprintf(s1, "lp -d%s", sa.print_dest)

cmd = exec.Command(s1)

tmp, err := cmd.StdinPipe()

wc = tmp

cmd.Start()

    //fout = popen(s1, "w");

    if (err != nil) {

fmt.Fprintf(os.Stderr, "%s: could not open pipe to \"%s\"\n",

      progname, s1)

      os.Exit(13)

    }

  }

  /* begin one of two main loops based on page type */

  if (sa.page_type == 'l') {

    line_ctr = 0;

    page_ctr = 1;

    for (true) {

line, err := inbuf.ReadString('\n')

      if (err != nil || io.EOF == err) {

        break

}

      line_ctr++

      if (line_ctr > sa.page_len) {

        page_ctr++

        line_ctr = 1

      }

      if ( (page_ctr >= sa.start_page) && (page_ctr <= sa.end_page) ) {

if (len(sa.print_dest) == 0) {

fmt.Fprintf(os.Stdout, "%s", line)

//wc.Write([]byte(line))

} else {

wc.Write([]byte(line))

}

      }

    }

  } else {

    page_ctr = 1;

    for (true) {

c, err := inbuf.ReadByte()

      if (err != nil) {

        break

}

      if (c == '\f') {

        page_ctr++

}

      if ( (page_ctr >= sa.start_page) && (page_ctr <= sa.end_page) ) {

bs := []byte{c}

//wc.Write(bs)

if (len(sa.print_dest) == 0) {

fmt.Fprintf(os.Stdout, "%c", c)

//wc.Write([]byte(line))

} else {

//wc.Write([]byte(line))

wc.Write(bs)

}

        //putc(c, fout);

      }

    }

  }

  /* end main loop */

  if (page_ctr < sa.start_page) {

fmt.Fprintf(os.Stderr,

"%s: start_page (%d) greater than total pages (%d), no output written\n",

progname, sa.start_page, page_ctr)

  } else if (page_ctr < sa.end_page) {

fmt.Fprintf(os.Stderr,

"%s: end_page (%d) greater than total pages (%d), less output than expected\n",

progname, sa.end_page, page_ctr)

  }

  if (err != nil) {

    s1 = "error,haha"

fmt.Fprintf(os.Stderr, "%s: system error [%s] occurred on input stream fin\n",

    progname, s1)

    os.Exit(14)

  } else {

    //wc.Flush()

fmt.Fprintf(os.Stderr, "%s: done\n", progname)

  }

}

/*================================= usage() =======================*/

func usage() {

fmt.Fprintf(os.Stderr,

"\nUSAGE: %s -sstart_page -eend_page [ -f | -llines_per_page ] [ -ddest ] [ in_filename ]\n", progname)

}

/*================================= EOF ===========================*/

猜你喜欢

转载自blog.csdn.net/qw7287653/article/details/83152370