【Unix/Linux编程实践】 动手实现简单的more

来源:互联网 发布:怎么做钓鱼软件 编辑:程序博客网 时间:2024/04/30 08:37

最近都在看一些理论方面的书,缺乏实践真的是云里雾里的,于是今天开始看《Unix/Linux编程实践教程》,理论实践相结合!

自己动手来实现linux的一些功能,确实挺有趣的,而且还能加深对系统的理解~

版本一

/*more01.c *read and print 24 lines then pause for a few special commands */#include <stdio.h>#define PAGELEN 24#define LINELEN 512/* *将数据显示在屏幕上,满一屏后,调用see_more函数接受用户的输入,以采取下一步动作。 */void do_more(FILE *);   int see_more();int main(int argc, char * argv[]){    FILE *fp;    //判断是文件还是标准输入,打开对应的数据源      if ( argc == 1)        do_more(stdin);    else    {        while (argc--)        if ( (fp = fopen(* ++argv, "r")) != NULL) //第一个参数是more01,跳过        {            do_more(fp);            fclose(fp);        }        else            exit(1);    }    return 0;}void do_more(FILE *fp){    char line[LINELEN];    int num_of_lines = 0;    int see_more(), reply;    while ( fgets(line, LINELEN, fp) )  //逐行读    {        if (num_of_lines == PAGELEN)    //满屏        {            reply = see_more();            if (reply == 0)                break;            num_of_lines -= reply;  //根据reply重置行数        }        if ( fputs(line, stdout) == EOF )            exit(1);        num_of_lines++;    }}int see_more(){    int c;    printf("\033[7m more? \033[m");    while ( (c = getchar()) != EOF )    //获取用户输入    {        if ( c == 'q' )     //退出            return 0;        if ( c == ' ' )     //下一页            return PAGELEN;        if ( c == '\n' )    //下一行            return 1;    }    return 0;}

当然这个程序存在挺多问题的,比如输入q和空格后,需要按回车,而且输入是有回显的。

另外,一个比较严重的问题是,如果我们进行重定向:

ls /bin | more01

则more01的标准输入被重定向到ls的标准输出中,这样子用户的输入也从这个输入流中读取,明显有问题。用户的输入应该始终从键盘读取,而不应该被重定向。

所以版本二提供了直接从键盘设备读取的功能。

版本二

设备文件/dev/tty是键盘和显示器的设备描述文件,往该文件写则显示在用户屏幕上,读则从键盘获取用户输入。

/*  more02.c  - version 0.2 of more *  read and print 24 lines then pause for a few special commands *      feature of version 0.2: reads from /dev/tty for commands */#include    <stdio.h>#define PAGELEN 24#define LINELEN 512void do_more(FILE *);int see_more(FILE *);int main( int ac , char *av[] ){    FILE    *fp;    if ( ac == 1 )        do_more( stdin );    else        while ( --ac )            if ( (fp = fopen( *++av , "r" )) != NULL )            {                do_more( fp ) ;                 fclose( fp );            }            else                exit(1);    return 0;}void do_more( FILE *fp )/* *  read PAGELEN lines, then call see_more() for further instructions */{    char    line[LINELEN];    int num_of_lines = 0;    int see_more(FILE *), reply;    FILE    *fp_tty;    fp_tty = fopen( "/dev/tty", "r" );     /* NEW: cmd stream   */    if ( fp_tty == NULL )              /* if open fails     */        exit(1);                           /* no use in running */    while ( fgets( line, LINELEN, fp ) ){               if ( num_of_lines == PAGELEN ) {                reply = see_more(fp_tty);  /* NEW: pass FILE *  */            if ( reply == 0 )                       break;            num_of_lines -= reply;      /* reset count  */        }        if ( fputs( line, stdout )  == EOF )    /* show line    */            exit(1);            /* or die   */        num_of_lines++;             /* count it */    }}int see_more(FILE *cmd)                /* NEW: accepts arg  *//* *  print message, wait for response, return # of lines to advance *  q means no, space means yes, CR means one line */{    int c;    printf("\033[7m more? \033[m");     /* reverse on a vt100   */    while( (c=getc(cmd)) != EOF )       /* NEW: reads from tty  */    {        if ( c == 'q' )                     return 0;        if ( c == ' ' )                     return PAGELEN;             if ( c == '\n' )                    return 1;           }    return 0;}

通过一个直观的例子感受了下Linux编程,虽然还有很多不完善的地方,但是完善本程序并不是我们的目的!

0 0
原创粉丝点击