#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;
#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 style="font-size:18px;">#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>