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