Chinaunix首页 | 论坛 | 博客
  • 博客访问: 929018
  • 博文数量: 177
  • 博客积分: 8613
  • 博客等级: 中将
  • 技术积分: 2835
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-12 04:16
文章分类
文章存档

2012年(12)

2011年(24)

2010年(24)

2009年(75)

2008年(42)

我的朋友

分类: C/C++

2009-08-02 20:47:40

    今天看了第十五章《输入/输出函数》,主要是介绍的一些I/O方面的库函数的用法,习题要求写一个unix上面grep程序的实现,这个grep的思路还是比较简单的:
1、处理命令行参数,将第一个参数当成是被查找的字符串,将后面的当成是文件名;
2、错误处理,如果命令行参数少于2个,就退出,打印帮助,如果只有字符串,没有文件名,则从标准输入读取;
3、在循环从文件中查找字符串时,原子操作为:
a、设置一个FILE *的结构指向文件,并打开文件;
b、用fgets函数一行一行地读文件;
c、用strstr库函数对刚才读的一行进行查找,如果找到,就把这行写到标准输出。

这样,我从最基本的版本做起,一步步实现了完整的fgrep,以下是具体的过程:

第一步:简单地从固定的文件里查找固定的字符串,这两个元素都是写死的,不支持命令行输入

[root@bjxdurs235 20090802]# cat fgrep_v1.c
#include
#include
#define MAX_LINE_CHAR 510
int main(void)
{
        char const *str_to_find = "hello";
        FILE *f ;
        char *line;

        f = fopen( "test.txt","r" );
        if ( f == NULL ){
                perror( "test.txt" );
                exit ( 1 );
        }

        char buffer[MAX_LINE_CHAR];
        while ( (line = fgets( buffer, MAX_LINE_CHAR, f )) != NULL ){
                if ( strstr( line, str_to_find ) != NULL ){
                        printf("%s:","test.txt");
                        fputs( buffer, stdout );
                }

        }


}
这个版本1是最原始,最基本的实现,以下的实现都是以这个为基本来做的扩展,在这个简单的实现里主要涉及了:
1、基本的文件操作,如fopen、fgets、fputs、peror等;
2、关键的strstr用对地方;

第二步:加入对命令行参数的简单处理
[root@bjxdurs235 20090802]# cat fgrep_v2.c
#include
#include
#define MAX_LINE_CHAR 510

void useage(void)
{
        printf("error!\nuseage:\nfgrep \"str\" filename filename ... \n");
}

int main( int argc, char **argv )
{
        if ( argc < 2 ){
                useage();
                exit ( 1 );
        }

        char const *str_to_find = *++argv;
        FILE *f ;
        char *line;
        while ( *++argv != NULL ){
                f = fopen( *argv,"r" );
                if ( f == NULL ){
                        perror( *argv );
                        //exit ( 1 );
                        continue;
                }

                char buffer[MAX_LINE_CHAR];
                while ( (line = fgets( buffer, MAX_LINE_CHAR, f )) != NULL ){
                        if ( strstr( line, str_to_find ) != NULL ){
                                printf("%s:",*argv);
                                fputs( buffer, stdout );
                        }

                }
        }

}

第三步:从文件中查找这个操作提炼成一个函数来做
[root@bjxdurs235 20090802]# cat fgrep_v3.c
#include
#include
#define MAX_LINE_CHAR 510

void useage(void)
{
        printf("error!\nuseage:\nfgrep \"str\" filename filename ... \n");
}

void my_grep( char const *str_to_find, char const *filename )
{
        FILE *f ;
        char *line;
        f = fopen( filename,"r" );
        if ( f == NULL ){
                perror( filename );
                //exit ( 1 );
                //continue;
                return ;
        }

        char buffer[MAX_LINE_CHAR];
        while ( (line = fgets( buffer, MAX_LINE_CHAR, f )) != NULL ){
                if ( strstr( line, str_to_find ) != NULL ){
                        printf("%s:",filename);
                        fputs( buffer, stdout );
                }

        }

}

int main( int argc, char **argv )
{
        if ( argc < 2 ){
                useage();
                exit ( 1 );
        }

        char const *str_to_find = *++argv;
        if ( argc == 2 ){
                /* process grep from stdin  */
                //my_grep( str_to_find, stdin );
        }
        else
        {
                while ( *++argv != NULL ){
                        my_grep( str_to_find, *argv );
                }
        }
}

第四步:完善功能,加入对stdin的支持
[root@bjxdurs235 20090802]# cat fgrep_v4.c
#include
#include
#define MAX_LINE_CHAR 510

void useage(void)
{
        printf("error!\nuseage:\nfgrep \"str\" filename filename ... \n");
}

void my_grep( char const *str_to_find, char const *filename )
{
        FILE *f ;
        char *line;
        if ( filename == NULL ){
                f = stdin;
        }
        else
        {
                f = fopen( filename,"r" );
        }
        if ( f == NULL ){
                perror( filename );
                //exit ( 1 );
                //continue;
                return ;
        }

        char buffer[MAX_LINE_CHAR];
        while ( (line = fgets( buffer, MAX_LINE_CHAR, f )) != NULL ){
                if ( strstr( line, str_to_find ) != NULL ){
                        printf("%s:",filename);
                        fputs( buffer, stdout );
                }

        }
        if ( f != NULL ){
                fclose(f);
        }

}

int main( int argc, char **argv )
{
        if ( argc < 2 ){
                useage();
                exit ( 1 );
        }

        char const *str_to_find = *++argv;
        if ( argc == 2 ){
                /* process grep from stdin  */
                //my_grep( str_to_find, stdin );
                my_grep( str_to_find, NULL );

        }
        else
        {
                while ( *++argv != NULL ){
                        my_grep( str_to_find, *argv );
                }
        }
}

   最后,这四个程序的行数是:
[root@bjxdurs235 20090802]# wc -l fgrep_v*
  26 fgrep_v1.c
  38 fgrep_v2.c
  51 fgrep_v3.c
  62 fgrep_v4.c
 177 total
    一步步地完善了这个功能,再看看习题的答案,估计人家又比我的精简,唉,刚开始写程序,总是这么繁杂,慢慢就会越来越熟练了。
阅读(1107) | 评论(0) | 转发(0) |
0

上一篇:删除单链表节点

下一篇:随机数发生器

给主人留下些什么吧!~~