linux上でwc-l-w-c+テキストファイルのような関数を実現する
9239 ワード
#include #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 ",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;loopfd){//開きに失敗した場合はloger(「open」);return;}if(fstat(fd,&statbuf){//ファイル記述子が開いているすべての情報//printf("fstat error[%s],strerror(errno));loger("fstat");return; } fsize = character = statbuf.st_size;//ファイルの総サイズmsize=ONE_MAX > fsize ? fsize : ONE_MAX ;//1回の読み取りサイズ、ケース1:1回の読み取りサイズ>合計サイズの場合、キャッシュfbuf[]の長さを//合計サイズに設定します.ケース2:1回の読み取りサイズ<合計サイズの場合、キャッシュごとにfbuf[]の長さを//読み取りごとのサイズloopcnt=fsize/msize+(fsize%msize>0);//ケース1であれば一度に読み終え、ケース2であれば、fbuf=(char*)malloc(msize+1)を何回読むかを計算しなければならない.//キャッシュは実は配列で、if(NULL==fbuf){printf(「malloc error[%s],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}
コードクリップを添付:
コードクリップを添付:
<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>
",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]
",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]
",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] || '
' == fbuf[index]){ //
if(!flag){ // 1,
word += 1;
flag = 1;
}
}else{
flag = 0;
}
if('
' == fbuf[index]){
line += 1;
}
index++;
}
loopcnt--;
if(' ' == fbuf[0] || '\t' == fbuf[0] || '
' == 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
",filename); //
return;
}
int main(int ac,char **av)
{
int fd = -1; // ,
do_work(ac,av); //
return 0;
}
</span>