c语言实现wc命令简单功能
 
程序功能简述

c语言实现了linux环境下的wc命令的功能

用法:mywc [选项]…[文件]…

打印出每个文件的字节数,词数,行数,如果文件数超过1个,还会打印出一行总计。当[文件] 缺省时,wc从标准输入设备(终端)读取,此时,[Esc] 键停止输入。

选项:

-c, –bytes 打印字节个数

-m, –chars 打印字母个数

-l, –lines 打印行数

-L, –max-line-length 打印最长行的字节数

-w, –words 打印词数

    –help 打印帮助信息并退出

    –version 打印版本信息并退出

 

编程要点

       1.对参数的出现与否设置标志量(flags)。

       2.在数的时候,明白何时字节数增1,何时字符数增1,何时行数增1,何时词数增1,最长行如何统计,在文件数大于1时,如何统计总合。

       3.需要先读取所有参数,然后再对参数种出现的文件进行统计,如果没有提供文件,则从终端读取并统计。

       4.有良好的用户帮助

 

实现结果:(mywc与系统wc对比)

 

 

[gary@localhost gary]$ ./mywc test

        6       7       23      test

 

[gary@localhost gary]$ ./mywc a b

        154     328     4224    a

        56      55      156     b

        210     383     4380    general

 

[gary@localhost gary]$ ./mywc -w b

        55      b

 

[gary@localhost gary]$ ./mywc -w b -c

        55      156     b

 

[gary@localhost gary]$ ./mywc -w b c -c

        55      156     b

        32      87      c

        87      243     general

 

[gary@localhost gary]$ ./mywc –help

usage: mywc [option]…[FILE]…

Print byte,word,and newline counts for each FILE,and a total line if more than one FILE is specified. With on File,read standard input, press key [Esc] to end inputting

        -c, –bytes     Print the byte counts.

        -m, –chars     Print the character counts.

        -l, –lines     Print the newline counts.

        -L, –max-line-length   Print the length of the longest line.

        -w, –words     Print the word counts.

            –help      Print this usage message and then exit

            –version   Print version information and then exit.

 

Report bugs to <gary@mail.hdss.org>.

 

[gary@localhost gary]$ ./mywc -L b -w

        55      2       b

 

[gary@localhost gary]$ ./mywc c -c –words

        32      87      c

 

[gary@localhost gary]$ ./mywc c -L -c –words

        32      87      2       c

 

[gary@localhost gary]$ ./mywc test -L -c –words

        7       23      6       test

 

[gary@localhost gary]$ ./mywc test b c -L -c –words

        7       23      6       test

        55      156     2       b

        32      87      2       c

        94      266     6       general

 

[gary@localhost gary]$ ./mywc

asdf

 g g

 

aaabc

^[

        4       4       17

 

[gary@localhost gary]$ ./mywc -L -wl

asdf

 g g

the longest line

^[

        3       6       16

 

[gary@localhost gary]$ ./mywc -w -

asdf sdf

sdf dsf

^[

        4

 

[gary@localhost gary]$ ./mywc -b b

mywc: wrong option -"b"

try "mywc –help" to get more infomations

 

[gary@localhost gary]$ ./mywc –hhelp

mywc: can’t identify option "–hhelp"

try "mywc –help" to get more infomations

 

[gary@localhost gary]$ cat >noC

[gary@localhost gary]$ ./mywc noC

        0       0       0       noC

 

 

[gary@localhost gary]$ wc test

      6       7      23 test

 

[gary@localhost gary]$ wc a b

    154     328    4224 a

     56      55     156 b

210     383    4380 总用量

 

[gary@localhost gary]$ wc -w b

     55 b

 

[gary@localhost gary]$ wc -w b -c

55               156 b

 

[gary@localhost gary]$ wc -w b c -c

     55     156 b

     32      87 c

     87     243 总用量

 

[gary@localhost gary]$ wc –help

用法:wc [选项]… [文件]…

Print byte, word, and newline counts for each FILE, and a total line if

more than one FILE is specified.  With no FILE, or when FILE is -,

read standard input.

  -c, –bytes            print the byte counts

  -m, –chars            print the character counts

  -l, –lines            print the newline counts

  -L, –max-line-length  print the length of the longest line

  -w, –words            print the word counts

      –help     显示此帮助信息并离开

      –version  显示版本信息并离开

 

Report bugs to <bug-coreutils@gnu.org>.

 

 

[gary@localhost gary]$ wc -L b -w

55                     2 b

 

[gary@localhost gary]$ wc c -c –words

32                  87 c

 

[gary@localhost gary]$ wc c -L -c –words

     32      87       2 c

 

[gary@localhost gary]$ wc test -L -c –words

      7      23       6 test

 

[gary@localhost gary]$ wc test b c -L -c –words

      7      23       6 test

     55     156       2 b

     32      87       2 c

     94     266       6 总用量

 

[gary@localhost gary]$ wc

asdf

 g g

 

aaabc

      4       4      17

 

 

[gary@localhost gary]$ wc -L -wl

asdf

 g g

the longest line

      3       6      16

 

 

[gary@localhost gary]$ wc -w -

asdf sdf

sdf dsf

      4 –

 

 

[gary@localhost gary]$ wc -b b

wc:无效选项 — b

请尝试执行‘wc –help’来获取更多信息。

 

[gary@localhost gary]$ wc –hhelp

wc:无法识别的选项“–hhelp

请尝试执行‘wc –help’来获取更多信息。

 

[gary@localhost gary]$ cat >noC

[gary@localhost gary]$ wc noC

      0       0       0 noC

 

 

[gary@localhost gary]$ ./mywc test

        6       7       23      test

 

[gary@localhost gary]$ ./mywc a b

        154     328     4224    a

        56      55      156     b

        210     383     4380    general

 

[gary@localhost gary]$ ./mywc -w b

        55      b

 

[gary@localhost gary]$ ./mywc -w b -c

        55      156     b

 

[gary@localhost gary]$ ./mywc -w b c -c

        55      156     b

        32      87      c

        87      243     general

 

[gary@localhost gary]$ ./mywc –help

usage: mywc [option]…[FILE]…

Print byte,word,and newline counts for each FILE,and a total line if more than one FILE is specified. With on File,read standard input, press key [Esc] to end inputting

        -c, –bytes     Print the byte counts.

        -m, –chars     Print the character counts.

        -l, –lines     Print the newline counts.

        -L, –max-line-length   Print the length of the longest line.

        -w, –words     Print the word counts.

            –help      Print this usage message and then exit

            –version   Print version information and then exit.

 

Report bugs to <gary@mail.hdss.org>.

 

[gary@localhost gary]$ ./mywc -L b -w

        55      2       b

 

[gary@localhost gary]$ ./mywc c -c –words

        32      87      c

 

[gary@localhost gary]$ ./mywc c -L -c –words

        32      87      2       c

 

[gary@localhost gary]$ ./mywc test -L -c –words

        7       23      6       test

 

[gary@localhost gary]$ ./mywc test b c -L -c –words

        7       23      6       test

        55      156     2       b

        32      87      2       c

        94      266     6       general

 

[gary@localhost gary]$ ./mywc

asdf

 g g

 

aaabc

^[

        4       4       17

 

[gary@localhost gary]$ ./mywc -L -wl

asdf

 g g

the longest line

^[

        3       6       16

 

[gary@localhost gary]$ ./mywc -w -

asdf sdf

sdf dsf

^[

        4

 

[gary@localhost gary]$ ./mywc -b b

mywc: wrong option -"b"

try "mywc –help" to get more infomations

 

[gary@localhost gary]$ ./mywc –hhelp

mywc: can’t identify option "–hhelp"

try "mywc –help" to get more infomations

 

[gary@localhost gary]$ cat >noC

[gary@localhost gary]$ ./mywc noC

        0       0       0       noC

 

 

[gary@localhost gary]$ wc test

      6       7      23 test

 

[gary@localhost gary]$ wc a b

    154     328    4224 a

     56      55     156 b

210     383    4380 总用量

 

[gary@localhost gary]$ wc -w b

     55 b

 

[gary@localhost gary]$ wc -w b -c

55               156 b

 

[gary@localhost gary]$ wc -w b c -c

     55     156 b

     32      87 c

     87     243 总用量

 

[gary@localhost gary]$ wc –help

用法:wc [选项]… [文件]…

Print byte, word, and newline counts for each FILE, and a total line if

more than one FILE is specified.  With no FILE, or when FILE is -,

read standard input.

  -c, –bytes            print the byte counts

  -m, –chars            print the character counts

  -l, –lines            print the newline counts

  -L, –max-line-length  print the length of the longest line

  -w, –words            print the word counts

      –help     显示此帮助信息并离开

      –version  显示版本信息并离开

 

Report bugs to <bug-coreutils@gnu.org>.

 

 

[gary@localhost gary]$ wc -L b -w

55                     2 b

 

[gary@localhost gary]$ wc c -c –words

32                  87 c

 

[gary@localhost gary]$ wc c -L -c –words

     32      87       2 c

 

[gary@localhost gary]$ wc test -L -c –words

      7      23       6 test

 

[gary@localhost gary]$ wc test b c -L -c –words

      7      23       6 test

     55     156       2 b

     32      87       2 c

     94     266       6 总用量

 

[gary@localhost gary]$ wc

asdf

 g g

 

aaabc

      4       4      17

 

 

[gary@localhost gary]$ wc -L -wl

asdf

 g g

the longest line

      3       6      16

 

 

[gary@localhost gary]$ wc -w -

asdf sdf

sdf dsf

      4 –

 

 

[gary@localhost gary]$ wc -b b

wc:无效选项 — b

请尝试执行‘wc –help’来获取更多信息。

 

[gary@localhost gary]$ wc –hhelp

wc:无法识别的选项“–hhelp

请尝试执行‘wc –help’来获取更多信息。

 

[gary@localhost gary]$ cat >noC

[gary@localhost gary]$ wc noC

      0       0       0 noC

 

程序流程图:


下面是对中间“读入参数设置flags”和“统计输出”分别细化的流程图:

.

.

.

.

(附)程序代码


///////////////////////////

//wc 命令功能c语言程序实现

//02101231 俞健伟

//

#include <ctype.h>

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

 

void showhelp(void); //显示帮助

void showversion(void); //显示版本

void showerr_s(char * s); //–string选项错误

void showerr_c(char c); //-char选项错误

int main(int argc, char * argv[])

{

     FILE *fp;

     int  nOver = 1;//屏幕输入状态

     int cflag = 0, mflag = 0, lflag = 0, Lflag = 0, wflag = 0;//统计对象标志

     int i = 0, j = 0, k = 0;

     char curChar,preChar;

     long noLines = 0,noWords = 0,noCharacters = 0,noBytes = 0,nomaxlen = 0;

     long tnoLines = 0,tnoWords = 0,tnoCharacters = 0,tnoBytes = 0,tnomaxlen = 0;//全局用量

     long lentemp = 0;

     char * filename[30];//mywc带的文件名

 

     for(i = 1; i<argc; i++)//读入所有参数,if argc == 1,not go into for{}

     {

         if(argv[i][0] == ‘-’)//is options

         {

              if(argv[i][1] == ‘-’)

              {

                   if(strcmp(argv[i],"–help")==0)

                   {

                       showhelp();

                       exit(0);

                   }

                   else if(strcmp(argv[i],"–version")==0)

                   {

                       showversion();

                       exit(0);

                   }

                   else if(strcmp(argv[i],"–bytes")==0)

                       cflag = 1;

                   else if(strcmp(argv[i],"–chars")==0)

                       mflag = 1;

                   else if(strcmp(argv[i],"–lines")==0)

                       lflag = 1;

                   else if(strcmp(argv[i],"–words")==0)

                       wflag = 1;

                   else if(strcmp(argv[i],"–max-line-length")==0)

                       Lflag = 1;

                   else

                   {

                       showerr_s(argv[i]);

                       exit(1);

                   }

              }

              else//short options

              {

                   for(j = 1; j<strlen(argv[i]); j++)

                   {

                       switch(argv[i][j])

                       {

                       case ‘c’:

                            cflag = 1;

                            break;

                       case ‘m’:

                            mflag = 1;

                            break;

                       case ‘l’:

                            lflag = 1;

                            break;

                       case ‘L’:

                            Lflag = 1;

                            break;

                       case ‘w’:

                            wflag = 1;

                            break;

                       default:

                            {

                                 showerr_c(argv[i][j]);

                                 exit(1);

                            }

                       }

                   }

              }

         }

         else//不是选项

         {//文件名处理

              filename[k] = argv[i];

              k++;

         }

     }//读完mywc所带所有参数

 

     if(k == 0)//不带文件名参数,统计屏幕输入

     {

         preChar = 0;

         curChar = getchar();

         noLines = 0;

         while(nOver)

         {

              switch(curChar)

              {

              case ‘\t’:

              case ‘ ‘:

                   if(preChar!=’ ‘&&preChar!=’\t’&&preChar!=’\n’&&preChar!=0)

                       noWords++;

                   noBytes++;

                   lentemp++;

                   break;

              case ‘\n’:

                   if(preChar!=’ ‘&&preChar!=’\t’&&preChar!=’\n’&&preChar!=0)

                       noWords++;

                   noLines++;

                   noBytes++;

                   if(lentemp>nomaxlen)

                       nomaxlen = lentemp;

                   lentemp = 0;

                   break;

              case 4:            //Ctrl+d, end of input

              case 0:            //Can’t be catched??? 

              case 27:      //Esc, end of input

                   nOver = 0;

                   if(preChar!=’ ‘&&preChar!=’\t’&&preChar!=’\n’&&preChar!=0)

                       noWords++;

                   break;

              default:

                   noBytes++;

                   lentemp++;

                   if(isalpha(curChar))

                       noCharacters++;

              }

              preChar = curChar;

              curChar = getchar();

         }

         //根据flags输出

         if(cflag == 0 && lflag == 0 && wflag == 0 && mflag == 0 && Lflag == 0)

              printf("\t%d\t%d\t%d\n",noLines,noWords,noBytes);

         else

         {

              if(lflag == 1)

                   printf("\t%d",noLines);

              if(wflag == 1)

                   printf("\t%d",noWords);

              if(cflag == 1)

                   printf("\t%d",noBytes);

              if(mflag == 1)

                   printf("\t%d",noCharacters);

              if(Lflag == 1)

                   printf("\t%d",nomaxlen);

              printf("\n");

         }

     }

     else//分别对每个文件进行统计,如果2个以上文件,计算全局用量general

     {

         for(j = 0; j<k; j++)

         {

              noLines = 0;

              noWords = 0;

              noCharacters = 0;

              noBytes = 0;

              if( (fp = fopen(filename[j],"r"))==NULL )

              {

                   printf("mywc: %s: not exists or other errors occur\n",filename[j]);

                   continue;

              }

              preChar = 0;

              while((curChar = fgetc(fp))!=EOF)

              {

                   switch(curChar)

                   {

                   case ‘\t’:

                   case ‘ ‘:

                       if(preChar!=’ ‘&&preChar!=’\t’&&preChar!=’\n’&&preChar!=0)

                            noWords++;

                       noBytes++;

                       lentemp++;

                       break;

                   case ‘\n’:

                       if(preChar!=’ ‘&&preChar!=’\t’&&preChar!=’\n’&&preChar!=0)

                            noWords++;

                       noLines++;

                       noBytes++;

 

                       if(lentemp>nomaxlen)

                       {

                            nomaxlen = lentemp;

                            if(nomaxlen>tnomaxlen)

                                 tnomaxlen = nomaxlen;

                       }

                       lentemp = 0;

                       break;

                   default:

                       noBytes++;

                       lentemp++;

                       if(isalpha(curChar))

                            noCharacters++;

                   }

                   preChar = curChar;

              }

         //读到EOF出循环后,判断

              if(preChar!=’ ‘&&preChar!=’\t’&&preChar!=’\n’&&preChar!=0)

              {

                   noWords++;

                   if(lentemp>nomaxlen)

                   {

                       nomaxlen = lentemp;

                       if(nomaxlen>tnomaxlen)

                            tnomaxlen = nomaxlen;

                   }

              }

              fclose(fp);

              //根据标志输出

              if(cflag == 0 && lflag == 0 && wflag == 0 && mflag == 0 && Lflag == 0)

                   printf("\t%d\t%d\t%d\t%s\n",noLines,noWords,noBytes,filename[j]);

              else

              {

                   if(lflag == 1)

                       printf("\t%d",noLines);

                   if(wflag == 1)

                       printf("\t%d",noWords);

                   if(cflag == 1)

                       printf("\t%d",noBytes);

                   if(mflag == 1)

                       printf("\t%d",noCharacters);

                   if(Lflag == 1)

                       printf("\t%d",nomaxlen);

                   printf("\t%s\n",filename[j]);

              }

         tnoLines += noLines;

         tnoWords += noWords;

         tnoCharacters += noCharacters;

         tnoBytes += noBytes;

         nomaxlen = 0;

         }

     }

     if(k>1)//文件数大于1

     {

         if(cflag == 0 && lflag == 0 && wflag == 0 && mflag == 0 && Lflag == 0)//use these as well

              printf("\t%d\t%d\t%d\tgeneral\n",tnoLines,tnoWords,tnoBytes);

         else

         {

              if(lflag == 1)

                   printf("\t%d",tnoLines);

              if(wflag == 1)

                   printf("\t%d",tnoWords);

              if(cflag == 1)

                   printf("\t%d",tnoBytes);

              if(mflag == 1)

                   printf("\t%d",tnoCharacters);

              if(Lflag == 1)

                   printf("\t%d",tnomaxlen);

              printf("\tgeneral\n");

         }

     }

     return 0;

}

 

/////////////////////

//showhelp

//

void showhelp(void)

{

     printf("usage: mywc [option]…[FILE]…\n");

     printf("Print byte,word,and newline counts for each FILE,and a total line if more than one FILE is specified. With on File,read standard input, press key [Esc] to end inputting\n");

     printf("\t-c, –bytes\tPrint the byte counts.\n");

     printf("\t-m, –chars\tPrint the character counts.\n");

     printf("\t-l, –lines\tPrint the newline counts.\n");

     printf("\t-L, –max-line-length\tPrint the length of the longest line.\n");

     printf("\t-w, –words\tPrint the word counts.\n");

     printf("\t    –help\tPrint this usage message and then exit\n");

     printf("\t    –version\tPrint version information and then exit.\n");

     printf("\nReport bugs to <gary@mail.hdss.org>.\n");

}

 

/////////////////////

//showversion

//

void showversion(void)

{

     printf("mywc by imitating wc in Redhat 9.0\n");

     printf("Written by Gary(02101231).\n");

     printf("This version is free.\n");

}

 

/////////////////////

//showerr_s

//

void showerr_s(char * s)

{

     printf("mywc: can’t identify option \"%s\"\n",s);

     printf("try \"mywc –help\" to get more infomations\n");

}

 

/////////////////////

//showerr_c

//

void showerr_c(char c)

{

     printf("mywc: wrong option -\"%c\"\n",c);

     printf("try \"mywc –help\" to get more infomations\n");

}

 


评论

该日志第一篇评论

发表评论

评论也有版权!