More命令实现

linuxmore命令的作用和cat比较类似,都是将文本文件的内容取出在屏幕上显示,简而言之就是基本的文件操作,只不过输出文件被定向到了屏幕上。

这里需要明白的是,在*NIX中,文件是一个很宽泛的概念,除了最普通的文本文件外,外设也被抽象成文件。

在用C语言完成more命令的编程时,我们首先需要明确的是我们的操作对象只是一般的文本文件,而不是广义上文件。在使用I/O函数时就得考虑是使用系统级I/O方式还是使用C语言自带的标准I/O方式。

比较二者的异同,我认为可以分为以下几点:

  • 系统级I/O不带缓冲区,直接完成内外存之间的数据传送。标准I/O带有用户级缓冲区,内容先被缓冲到用户态进程的内存空间中。

  • 系统级I/O使用openreadwrite等函数,open打开文件并返回int类型的文件句柄,标准I/O使用fopenfreadfwrite等函数进行操作,使用fopen打开文件后返回的是指向FILE类型结构体的指针。

  • 随机访问文件是系统级I/O速度更快,顺序访问文件时标准I/O更快。

  • 系统级I/O多用于处理设备文件,标准I/O多用于处理文本文件。

综上,在实现more命令时,最好还是选择标准I/O提供的功能。

要实现more命令首先要说明more命令最基本的操作和功能。在命令行下more的基本使用方式是:more filename,通过调用more命令将所给定文件的内容读取出来。当文件内容超过我们所设定的一页大小时,可以通过输入信息进行接下来的操作。输入回车键将会对显示一行的内容,输入空格键将会多显示一页的内容,输入字母q将会退出more程序。

代码如下:

#include <stdio.h>

#include <stdlib.h>

 

#define PAGELEN 24

#define LINELEN 100

 

void do_more(FILE *);

int see_more(FILE *);

 

int main(int argc, char *argv[])

{

    FILE *fp;

    if(argc == 1)

       do_more(stdin);

    else

       while(–argc){

           if((fp = fopen(“* (++argv)”, “r”)) != NULL){

              do_more(fp);

              fclose(fp);

           }

           else

              exit(1);

       }

    return 0;

}

 

void do_more(FILE *fp)

{

    char line[LINELEN];

    int num_of_lines = 0;

    int reply;

    FILE *fp_tty;

    fp_tty = fopen(“/dev/tty”, “r”);

    if (fp_tty == NULL)

       exit(1);

    while(fgets(line, LINELEN, fp)){

       if (num_of_lines == PAGELEN){

           see_more(fp_tty);

           if(reply == 0)

              break;

           num_of_lines -= reply;

       }

       if(fputs(line, stdout) == EOF)

           exit(1);

       ++num_of_lines;

    }

    printf(“\n”);

}

 

int see_more(FILE *cmd)

{

    int c;

    printf(“\n:”);

    while((c = getc(cmd)) != EOF)

    {

       if(c == ‘q’)

           return 0;

       if(c == ‘ ‘)

           return PAGELEN;

       if(c == ‘\n’)

           return 1;

    }

    return 0;

}

上述代码中,关于文件的标准I/O操作上一篇文章已经说过了,需要补充的是argcargv的意义。在命令行下执行程序的时候除了输入程序名之外有时候还要输入程序执行的参数,这里的参数可以通过argcargv在主程序中取得并采取相应的操作,属于交互模式下的C程序。

比如我们将编译好的程序命名为more并在本目录下执行,则需要在命令行下输入以下语句:

more file1name [……]

假设我们只输入了一个文件名,则这时argc的值为2,也就是morefile1name这两个参数的数量,同理,如果我们输入两个文件名,则这时argc的数量为3。至于argv,它本身是一个指针数组,数组中每个元素都是指向字符串的指针,比如argv[0]是指向字符串more的指针,argv[1]是指向字符串file1name的指针。在代码中我们也是通过* (++argv)来取得所需打开的文件的文件名,并将此作为fopen函数的参数用来打开文件的。

 

 

 

 

 

 

      

 

Advertisements