#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>