歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux技術 >> 實現linux上類似wc

實現linux上類似wc

日期:2017/3/3 13:01:36   编辑:Linux技術

#include <apue.h>

#define LINE_AVA 1

#define WORD_AVA 2 //用一個變量可以表示三個信息

#define CHAR_AVA 4

#define ONE_MAX 10 //一次能讀的最多的字節數

void do_work(int,char **);

void do_count(char *,int);

void do_work(int ac,char **av)

{

int rst = -1;

int how = 0;

int loop=0;

int index=0;

if(1 >= ac || NULL == av){ //如果參數小於等於1,即沒有參數,或av 指向不合法,退出

return ;

}

for(loop=1;loop<ac;++loop){

if('-' == av[loop][0]){ //判斷是否有參數前面的 " - "

index = 1;

while('\0' != av[loop][index]){ //判斷" - "後面的參數是否為 "w","l","c"等

switch(av[loop][index]){ //注意switch 後面只能跟字符常量或整型常量

case 'w':

how |= WORD_AVA ; //用位運算操作節省了變量 how = 2 ,2就是權重

break;

case 'l':

how |= LINE_AVA; //1

break;

case 'c':

how |= CHAR_AVA; //4

break;

default:

printf("Usage : %s <-w|c|l> <filename>\n",av[0]);

return ;

break;

}//end switch

++index;

}//end while

}//end if

}//end for

if(0 == how){

how = WORD_AVA | LINE_AVA | CHAR_AVA ;

}

for(loop=1;loop<ac;++loop){

if('-' != av[loop][0]){

do_count(av[loop],how);

}

}

return;

}

void do_count(char *filename,int how)

{

int fd = -1;

int word=0;

int line=0; //多少行

int character=0; //多少個字符

int fsize=0; //文件總大小

int msize=0; //每次讀的大小

int loopcnt = 0; //如果每次讀的大小小於總大小,要讀的次數

int index = 0;

int flag = 0;

struct stat statbuf; //定義一個結構體statbuf,而它聲明的結構體原型stat則在 sys/stat.h 中聲明

char *fbuf = NULL;

if(NULL == filename){

return ;

}

fd = open(filename,O_RDONLY,0600); //打開文件,並給於權限

if(0 > fd){ //若打開失敗,則返回

logerr("open");

return ;

}

if(fstat(fd,&statbuf)){ //獲取到已打開文件描述符的所有信息

//printf("fstat error [%s]\n",strerror(errno));

logerr("fstat");

return;

}

fsize = character = statbuf.st_size; //文件的總大小

msize = ONE_MAX > fsize ? fsize : ONE_MAX ;//每次讀的大小,情況1:如果每次讀的大小 > 總大小,則每次緩存fbuf[]的長度設為

//總大小,情況2:如果每次讀的大小 < 總大小,則每次緩存fbuf[]的長度設為

//每次讀的大小

loopcnt = fsize / msize + (fsize%msize > 0);//如果是情況1,則一次讀完,如果是情況2,必須計算讀多少次

fbuf = (char *)malloc(msize+1); //緩存其實就是數組,

if(NULL == fbuf){

printf("malloc error [%s]\n",strerror(errno));

return;

}

fbuf[msize] = '\0';

/*

* 計算fbuf[]裡面 單詞數量的的算法

* _______hello____word_____liusenlin__ 這裡單詞不包括換行時候 例如liusen-lin 開頭有"_" -1

* +1 2 3 4

*

* liusenlin_______nihao__________good__ 無 不用-

* 1 2 3

*

* liusenlin_______nihao__________good 當出現這種 算法出現bug

*

* 然而本次選取的fbuf長度足夠大,所以並未出現意外

*

* */

while(loopcnt){ //循環讀

memset(fbuf,'\0',msize); //每次讀必須清除緩存

read(fd,fbuf,msize);

index = 0;

while(index < msize){

if(' ' == fbuf[index] || '\t' == fbuf[index] || '\n' == fbuf[index]){ //如果每次開始就有特殊字符則單詞

if(!flag){ //加1,並且

word += 1;

flag = 1;

}

}else{

flag = 0;

}

if('\n' == fbuf[index]){

line += 1;

}

index++;

}

loopcnt--;

if(' ' == fbuf[0] || '\t' == fbuf[0] || '\n' == fbuf[0]){ //如果每次開始就有特殊字符,則進行減一

word -= 1;

}

}//end while

free(fbuf); //釋放

if(LINE_AVA & how){ //相等 與運算 ,則執行對應的

printf(" %d ",line);

}

if(WORD_AVA & how){ //

printf(" %d ",word);

}

if(CHAR_AVA & how){ //

printf(" %d ",character);

}

printf("%s\n",filename); //

return;

}

int main(int ac,char **av)

{

int fd = -1; //初始文件描述符一般為非法值,因為文件描述符為大於零的數

do_work(ac,av); //傳入命令行的參數

return 0;

}

附上代碼片段:

<span >#include <apue.h>

#define LINE_AVA    1
#define WORD_AVA    2       //用一個變量可以表示三個信息
#define CHAR_AVA    4

#define ONE_MAX     10    //一次能讀的最多的字節數

void do_work(int,char **);
void do_count(char *,int);

void do_work(int ac,char **av)
{
    int rst = -1;
    int how = 0;
    int loop=0;
    int index=0;

    if(1 >= ac || NULL == av){     //如果參數小於等於1,即沒有參數,或av 指向不合法,退出
        return ;
    }
    for(loop=1;loop<ac;++loop){
        if('-' == av[loop][0]){        //判斷是否有參數前面的 " - "
            index = 1;
            while('\0' != av[loop][index]){      //判斷" - "後面的參數是否為 "w","l","c"等
                switch(av[loop][index]){         //注意switch 後面只能跟字符常量或整型常量
                   case 'w':
                       how |= WORD_AVA ;    //用位運算操作節省了變量     how = 2   ,2就是權重
                       break;
                   case 'l':
                       how |= LINE_AVA;      //1
                       break;
                   case 'c':
                       how |= CHAR_AVA;     //4
                       break;
                   default:
                       printf("Usage : %s <-w|c|l> <filename>\n",av[0]);
                       return ;
                       break;
                }//end switch
                ++index;
            }//end while
        }//end if
    }//end for

    if(0 == how){
        how = WORD_AVA | LINE_AVA | CHAR_AVA ;
    }

    for(loop=1;loop<ac;++loop){
        if('-' != av[loop][0]){
            do_count(av[loop],how);
        }
    }
    return;
}

void do_count(char *filename,int how)
{
    int fd = -1;
    int word=0;
    int line=0;     //多少行
    int character=0;   //多少個字符
    int fsize=0;       //文件總大小
    int msize=0;        //每次讀的大小
    int loopcnt = 0;      //如果每次讀的大小小於總大小,要讀的次數
    int index = 0;
    int flag = 0;
    struct stat statbuf;      //定義一個結構體statbuf,而它聲明的結構體原型stat則在 sys/stat.h 中聲明 
    char *fbuf = NULL;

    if(NULL == filename){
        return ;
    }
    fd = open(filename,O_RDONLY,0600);  //打開文件,並給於權限
    if(0 > fd){                     //若打開失敗,則返回
        logerr("open");
        return ;
    }
    if(fstat(fd,&statbuf)){    //獲取到已打開文件描述符的所有信息
        //printf("fstat error [%s]\n",strerror(errno));
        logerr("fstat");
        return;
    }
    fsize = character = statbuf.st_size;       //文件的總大小
    msize = ONE_MAX > fsize ? fsize : ONE_MAX ;//每次讀的大小,情況1:如果每次讀的大小 > 總大小,則每次緩存fbuf[]的長度設為
                                                //總大小,情況2:如果每次讀的大小 < 總大小,則每次緩存fbuf[]的長度設為
                                                //每次讀的大小
    loopcnt = fsize / msize + (fsize%msize > 0);//如果是情況1,則一次讀完,如果是情況2,必須計算讀多少次
    fbuf = (char *)malloc(msize+1);    //緩存其實就是數組,
    if(NULL == fbuf){
        printf("malloc error [%s]\n",strerror(errno));
        return;
    }
    fbuf[msize] = '\0';
/*
 *                    計算fbuf[]裡面 單詞數量的的算法
 *    _______hello____word_____liusenlin__      這裡單詞不包括換行時候 例如liusen-lin    開頭有"_"   -1
 *    +1          2       3             4
 *
 *   liusenlin_______nihao__________good__        無   不用-
 *             1          2             3
 *
 *   liusenlin_______nihao__________good    當出現這種          算法出現bug
 *
 *   然而本次選取的fbuf長度足夠大,所以並未出現意外
 *
 * */
    while(loopcnt){                   //循環讀
        memset(fbuf,'\0',msize);         //每次讀必須清除緩存
        read(fd,fbuf,msize);
        index = 0;
        while(index < msize){
            if(' ' == fbuf[index] || '\t' == fbuf[index] || '\n' == fbuf[index]){   //如果每次開始就有特殊字符則單詞
                if(!flag){                                            //加1,並且
                    word += 1;
                    flag = 1;
                }
            }else{
                flag = 0;
            }
            if('\n' == fbuf[index]){
                  line += 1;
            }
            index++;
        }
        loopcnt--;
        if(' ' == fbuf[0] || '\t' == fbuf[0] || '\n' == fbuf[0]){    //如果每次開始就有特殊字符,則進行減一
            word -= 1;
        }
    }//end while
    free(fbuf);      //釋放

    if(LINE_AVA & how){       //相等  與運算    ,則執行對應的
        printf(" %d ",line);
    }
    if(WORD_AVA & how){        //
        printf(" %d ",word);
    }
    if(CHAR_AVA & how){        //
        printf(" %d ",character);
    }
    printf("%s\n",filename);     //

    return;
}

int main(int ac,char **av)
{
    int fd = -1;         //初始文件描述符一般為非法值,因為文件描述符為大於零的數

    do_work(ac,av);      //傳入命令行的參數
    return 0;
}
</span>

Copyright © Linux教程網 All Rights Reserved