2005年07月01日
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");

}

 

c语言实现more命令简单功能
 
程序功能简述
        利用linux下的curses库,用c语言实现了linux环境下的more命令的功能子集,能够在24*80的终端(窗口)屏幕全屏翻屏。
        键入mmore filename 后(mMore.c源文件编译成可执行文件mmore),mmore先初始化自己的窗口,然后分屏显示文件内容。
        键盘按键:
                n/N往下翻屏(无需回车,直接接收,屏幕不显示所按键对应字符)
                b/B 往回翻屏(无需回车,直接接收,屏幕不显示所按键对应字符)
                q/Q 退出more并关闭窗口,回到终端。(无需回车,直接接收,屏幕不显示所按键对应字符)
 
编程要点
       1.需要知道curses库中常用函数,会使用这些函数。
       2.文件需要读到缓冲(buffer)中,以方便频繁换屏显示时读取所需内容。
       3.建立数据结构,存储每屏显示开始点在buffer中的确切位置,当需显示该屏内容时,及时找到起始点读取并显示。
       4.处理长于80byie的行恰好位于前后两屏显示的中间时的情况。(比如一行有90字节,则前80字节在一屏结束行显示,后10字节在接下去一屏的开始行显示。)
       5.编译时不要忘记连接ncurses库。(我用:gcc mMore.c –o mmore –l ncurses)
 
实现结果
程序流程图

(附)程序代码


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

///more 功能的c语言实现

///02101231 Gary

///

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <curses.h>

 

#define SCREEN_LINES 22     //show (0->SCREEN_LINES)SCREEN_LINES+1 lines

int getoneline(char * a);   //得到一行的长度

 

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

{

     FILE *fp;

     char filename[20];

     long filelength, pointer;

     char *buffer;          //文件缓冲

     char CLine[512], key;

     int linenum, curline;

     int i,len, *points,p;

     int curX,curY, preY;        //光标在屏幕中的坐标(Y为行,X为列)

 

     if(argc < 2)

     {

         fprintf(stderr, "usage: %s filename\n",argv[0]);

         exit(1);

     }

 

     strcpy(filename, argv[1]);

 

     if((fp = fopen(filename, "r")) == NULL)   //打开文件

     {

         fprintf(stderr,"file %s can not be opened!\n", filename);

         exit(2);

     }

 

     filelength = 0L;

     fseek(fp, 0L, SEEK_END);

     filelength = ftell(fp);              //得到文件长度

 

     if((buffer = (char*)malloc(filelength+1)) == NULL)

     {

         fprintf(stderr,"not enough memery for store the file!\n");

         exit(3);

     }

 

     memset(buffer,0×00,filelength+1);

 

     fseek(fp, 0l, SEEK_SET);

 

     linenum = 0;

     pointer = 0L;

 

     while(!feof(fp))   //文件进缓冲

     {

         memset(CLine,0×00,512);

         fgets(CLine,512,fp);        //Cline 可能越界,不过前面memset0了,因该可以。

         len = strlen(CLine);

         strncat(buffer + pointer, CLine, strlen(CLine));

         pointer += strlen(CLine);

         if( len/80>0 && len%80>0 )

              linenum += len/80+1;

         else if(len>80 && len%80==0)

              linenum += len/80;

         else

              linenum++;

     }

 

     for(i = 0; i<filelength+1; i++)      //有些文件的行末不光一个‘\n’,而以"\r\n"结束,去‘\r’

     {                                    //否则addstr(str),或printw(format,str)对它不能正常显示

         if(*(buffer+i)==’\r’&&*(buffer+i+1)==’\n’)

              *(buffer+i)=’ ‘;

     }

 

     if( (points = (int *)malloc((linenum/SCREEN_LINES +1)*sizeof(int))) == NULL )//每屏始点记录数组

     {

         fprintf(stderr,"not enough memery!");

         exit(3);

     }

 

     pointer = 0l;

     curline = 0;

     p = -1;

 

     curX = curY = preY = 0;

     initscr();         //初始化窗口

     cbreak();     //除了 DELETE CTRL 等仍被视为特殊控制字元外一切输入的字元将立刻被一一读取

     noecho();     //屏幕上不显示在终端上

     intrflush(stdscr,FALSE);    //??不是很清楚。。。

     keypad(stdscr,TRUE);        //可以使用键盘上的一些特殊字元, 如上下左右等方向键

     refresh();         //首次使用,清屏

     while(1)

     {

         move(curY,curX);

         if(curline == 0)

         {

              //record the point that may return;

              points[++p] = pointer;

         }

         len = getoneline(buffer + pointer);

         memset(CLine,0×00,512);

         strncpy(CLine,buffer + pointer, len);

         printw("%s",CLine);         //在窗口屏幕中输出CLine

         preY = curY;

         getyx(stdscr,curY,curX);//得到当前的光标坐标

         if(curY>SCREEN_LINES)  //长行跨屏显示时,pointer记录下一屏的起始点的正确地点

         {

              if(len<=(SCREEN_LINES+1-preY)*80)

                   pointer += len;

              else

                   pointer += (SCREEN_LINES+1 – preY )*80;

         }

         else                   //一般情况下的pointer

              pointer += len;

         curline = curY;

         if(curY>SCREEN_LINES || p*(SCREEN_LINES+1)+curY+1>=linenum )//屏幕显示满,或文件终结

         {

              mvprintw(SCREEN_LINES+1,0,"                                                                                ");

              attron(A_REVERSE);

              mvprintw(SCREEN_LINES+1,0,"  —This is Gary(02101231)’s mmore!—  [ b/B: back, n/N: next, q/Q: quit ]   ");

              attroff(A_REVERSE);

              move(SCREEN_LINES+1,79);

              refresh();         //显示屏幕给用户看

wait:

              key = getch();     //得到按键命令[ b/B: back, n/N: next, q/Q: quit ]

              switch(key)

              {

              case ‘b’:

              case ‘B’:

                   if(p>0)       //得到需要的起始点,points数组中已存

                   {

                       pointer = points[--p];//point at SCREEN_LINES or n lines before

                       p–;

                   }

                   else

                   {

                       pointer = 0;

                       p–;

                   }

                   curY=curX=0;

                   curline = 0;

                   clear();      //清屏

                   break;

              case ‘n’:

              case ‘N’:

                   if(p*(SCREEN_LINES+1)+curY+1 >= linenum)//文件终结,不能下翻页

                   {

                       goto wait;

                   }

                   curY=curX=0;

                   curline = 0;

                   clear();      //清屏

                   break;

              case ‘q’:

              case ‘Q’:

                   endwin();     //结束,关闭窗口,回到终端。

                   exit(0);

                   break;

              default :

                   goto wait;

                   break;

              }

         }

     }

 

     endwin();

     fclose(fp);

     free(points);

 

     return 0;

}

 

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

///getoneline

///

int getoneline(char * a)

{

     int lenofline = 0;

     while(*a != ‘\n’ && *a != ‘\0′)

     {

         lenofline++;

         a++;

     }

     if(*a == ‘\n’)

         lenofline++;

     return lenofline;

}

2005年06月29日

许多人身在城市,离农村有距离,对农村现状,尤其对农村的民主政治并不了解。也许仅有的了解也是从新闻里看来的。

好像前几年才开始的村民自选村长(也许搞错,不过之前我没见过投票之类的事),于是,村里的有钱人在“有钱有势”以后,就开始想有权了。每次选举之前,总有人过来拉选票,总是亲戚或是走得比较近的,关系比较好的人过来游说。不仅畅谈亲情、朋友,还有甚直接说,选谁谁谁就给一条烟什么的。

原本就是一个小村子,村里人早上不见晚上见的,都是熟人,参加竞选的人可能同时都是一家人的关系密切的人,有人来拉选票,让人左右为难,不知道该怎么应对。这时,弃权算是办法了。

这次村里选村长,听我妈说,村里人好像分成了两派,分别拥护两个候选人。我去凡(小我2岁的小伙子,刚考上大学)家给他电脑装系统,他也说到村里选举的事。因为他叔叔是候选人之一(现在已经是村长了),所以他回去,很多人好像都不欢迎他,他说:“平时关系那么好的人,选了一下村长,都对你白眼一翻一翻的。还是在镇上不回去来得清心。”

我因为在学校,对村里的事关心得少了。不过,从听说的事来看,村里的选举真值得思考一下。听说现任村长(凡的叔叔)扬言,村支书在选举时帮另一边,等他成为党员,他要搞掉现任村支书。哎!这事真的值得如此仇恨吗?民主的推行就那么困难吗?人家在选举时支持哪边是自由的,难道非支持自己不可?有些霸道了。村里有钱人都有些霸道,不能否认。爷爷在现任村长的人来拉票时,说:“我不选他的,我选***的”,现在看来,也是得罪人了啊。妈开始说爷爷那么大年纪了,还不会明哲保身,说随便找个不得罪人的借口就可以了嘛。

记得同学(嵊州的)说,他们那里有个村两派选村长都弄出人命了,因为一方选上村长,另一方把他捅了。人到底是怎么搞的,难道当上村长的油水真的那么多(我知道村长工资很低)?多到可以让人丧失理智而行凶?记得另一个同学(义乌的)说,他们村(土地要征用)里选村长,两派人是1000块一张选票来买的。到后来,还差一票定输赢,结果那一票被炒到几万块。

我觉得,农村选举确实需要改善一下,目前的制度还不完善,出现了让人很担心的情况。长此下去,对社会稳定也是一个威胁。想象一下,一个村里分成两派,两派之间明争暗斗,加上农村人本身素质不高,小小问题可能就引起殴斗,不稳定因素增加了。

首先,关于村长的责任、权力、油水,需要制度来规范;让他们在就职前许诺村里人,在任职期间对村里那些不足予以改进,对那些地方进行改革,会做那些对村里有益的事。。。。。。我觉得竞选演讲就是一个很好的方式,他在大家面前许了诺,好坏大家有目共睹。

其次,选举过程需要制度来规范,让他们不能一家一家,一个人,一个人的盯着拉选票。这个东西实现起来比较难,属理想状态下的东西。

再次,对村民需要进行各种相关教育。让他们懂得什么是民主,什么是霸道。要让他们的素质有所提高,不至于小问题引发暴力事件。

还有,以后再想了。。。呵呵

我感觉现在农村的选举有些变味,不知道有关部门有没有重视。我也不对所谓的高层抱太大期望,因为上有政策,下有对策。高层期望很好,但一下底层就面目全非了。不是下面执行人不知道怎么去正确地做,而是在是利益相关,为利而不得不让某些东西在下面走样。

前天回家了。

带了本书回去看,看了两页,就看不进去了,现在唯一还有印象的是说到舜在寻找治水的人,群臣都说鲧可以,但舜顾及族人声誉,说:鲧(系黄帝后人)背负天命,怕水难治,有损同族人声誉,不能任用。 尽管后来还是用鲧,但我想,怎么那么原始的年代,人们就开始注意到族人声誉问题,开始明哲保身了?中国文化还真是源远流长啊。

妈好久没见我了,杭州和富阳那么近,我都有几个月没回去了。她真是越来越会管我了,动身回学校之前,我猛喝水,她叫我去吃西瓜,叫我不要喝水了,水带着路上喝。我说我不要吃西瓜,我当时真不想吃西瓜,还说她怎么那么喜欢管人了。妈说我不会打算,还嫌被管了。 她送我到公交车站,临我上门还在我身后叮嘱:到综合市场下车     我的妈妈啊,我都那么大岁数了,坐公交车哪里下车还不知道啊?她是一直把我看成是小孩子了。这种感觉真不爽。明明是大人了嘛,还把人家当小孩子。

不过我心里是很明白的,妈是关心我,设身处地为我想了,而想的同时,把话从嘴里说了出来。她见我喝水,她在想:西瓜也解渴,怎么不吃西瓜? 见我上车,她想到,该在综合市场下车,然后转车的。这些都是她思想中在为我设身处地为我在想,想到了就说了出来,也不顾及我是不是喜欢她那么说。我很感激,因为她始终都在为我着想着,尽管被人当小孩子有些不爽,但她是我妈,被她看成小孩子是在情理之中。呵呵

写得有些乱了,呵呵

2005年06月13日

上个月的这个时候,是博文的生日。我给他发了条短信捎去祝福。记得当天校园海报说李阳要来体育场演讲。最初接触李阳的疯狂英语,是在高中。那次林伟叔叔碰巧在富阳,又碰巧让我碰到了,他正给新丰买书,也给我买了很多书。我就在那家书店看到了李阳的《疯狂英语.成功之路》了。后来,我把它买了下来。

买回来以后,我真努力学了一段时间,基本把发音关过了。至少我能听出什么样的英语好听,什么样的英语太生硬。它里面带了英文句子卡片的,很多,有百来张吧,具体有多少我忘了。我空时就拿张背背,博文也背,我看他要背得比我多。也许他喜欢这样的方式,比如排队买饭时,就可以背下两三个句子。这样很充分利用边角料时间。

我确实看出他喜欢这样的方式背英文了,于是,我去外面一家店里零买了《成功之路》里的那包卡片,在他生日的时候送给了他,希望他会喜欢。呵呵

这小子好像现在很牛了,他上次和我说,他们专业课老师是外国人,上课都全英文的,作业也用英文做,上台作报告也用英文。我看我是及不上他了。上次,我去他学校玩,看见他有同学来问他英文题目,想必他英文确实应该不错了。我可是好几年没背过单词了,唯一和英文还有接触是在看外国电影的时候,偶尔学一两句话,哎。。。

夫君子之行,静以修身,俭以养德。非淡泊无以明志,非宁静无以致远。
夫学须静也,才须学也,非学无以广才,非志无以成学。淫慢则不能励精,险躁则不能治性。年与时驰,意与日去,遂成枯落,多不接世,悲守穷庐,将复何及!
回想起高中时和博文一起背《诫子书》的情景。那次他假日去建德他爸那边(当时他爸在建德工作),去了兰溪诸葛村,和我讲了他的所见所闻,还给我带来了礼物,那就是那份《诫子书》了。他说,我们一起把它背下来吧。于是,我们就把它背了下来。
到前段时间,我对其中两句已经淡忘的时候,我去找来了我的一个老书签,再背了一下现在应该可以被出来的。因为当时刚好看到有页纸上有《诫子书》,而且那本书也不用,所以撕下来折成书签了。
遗忘是正常的,但是对美好的经历的遗忘确实是件很可惜的事。我时常想起以前的一些事,但也时常在忘记一些事。每当我记起一些事的时候,总有种舒服的感觉,有时也觉得自己幼稚,我是不是已经老了?怎么会有那么多的回忆?
2005年06月09日

http://blog.chinaunix.net/article.php?articleId=5539&blogId=2108

试图粘过来的,不过出错了,说 : 文章中出现禁止的词语,系统不予接受。

http://www.xnovo.com/doc/html/afaebd/bhaebgaaauhmsvphluwj.html

作者:zgl

邮箱:yoshiro_gl@21cn.com



  发现大多数人对VB中应用指针不太了解,作一些说明。

  VB的指针挺简单的,用着也很方便,其实对象变量就可以看成是指针,当你用Set A=Obj时,A就是指向Obj的地址。不用API就可以,当然用API可以实现更为高级的结构。

  给一个例子,一个用VB实现的双向循环链表。有链表的生成,删除和结点的插入。

  先定义一个结点类,类名为Node,代码为:



Option Explicit

Public pNext As Node

Public pPrev As Node

Public data As Single



Private Sub Class_Initialize()

  Set pNext = Nothing

  Set pPrev = Nothing

End Sub



Private Sub Class_Terminate()

  Set pNext = Nothing

  Set pPrev = Nothing

End Sub



再添加一个窗体,窗体上添加两个列表框,list1和list2,窗体的代码为:



Option Explicit

Private pHead As Object

Private pV As Object



Private Sub Form_Load()

Dim i As Integer

  Set pHead = New Node

  Call CreateLinkList

  Call InsertNode(pHead, 503)

  Call InsertNode(pHead, 1.875)

  Call InsertNode(pHead, -3.675)

  For i = 1 To 100

    Call InsertNode(pHead, -1 * i)

  Next

  Call PrintList

  Call DeleteList

End Sub



Public Sub CreateLinkList()

Dim p As Node

Dim nLoop As Integer

Static pLast As Node

pHead.data = 0

Set pLast = pHead

For nLoop = 1 To 501

  Set p = New Node

  p.data = nLoop

  Set pLast.pNext = p

  Set p.pPrev = pLast

  Set pLast = p

Next

Set pLast = Nothing

Set p.pNext = pHead

Set pHead.pPrev = p

Exit Sub

End Sub



Public Sub PrintList()

List1.AddItem "Forwards"

Set pV = pHead

Do

  List1.AddItem pV.data

  Set pV = pV.pNext

Loop While Not pV Is pHead



List2.AddItem "Backwards"

Set pV = pHead.pPrev

Do

  List2.AddItem pV.data

  Set pV = pV.pPrev

Loop While Not pV Is pHead.pPrev

End Sub



Public Sub DeleteList()

Dim p As Node

Set pV = pHead

Do

  Set pV = pV.pNext

  Set p = pV.pPrev

  If Not p Is Nothing Then

    Set p.pNext = Nothing

    Set p.pPrev = Nothing

  End If

  Set p = Nothing

Loop While Not pV.pNext Is Nothing

Set pV = Nothing

Set pHead = Nothing

End Sub



Public Sub InsertNode(head As Node, data As Single)

Dim p As New Node, q As Node, prev As Node

p.data = data

Set q = head

Set prev = head.pPrev

While ((q.data < p.data) And Not q.pNext Is head)

  Set q = q.pNext

  Set prev = prev.pNext

Wend

If Not q.pNext Is head Then

  Set p.pNext = q

  Set p.pPrev = prev

  Set prev.pNext = p

  Set q.pPrev = p

  If q Is head Then

    Set head = p

  End If

Else

  Set p.pNext = head

  Set p.pPrev = q

  Set head.pPrev = p

  Set q.pNext = p

End If

End Sub



  一个双向循环链表就形成了,List1中是正向遍历的结果,List2中是反向遍历的结果。类的构造器Class_Initialize()过程,类的析构Class_Termainate()过程,结点内存的分配和回收都由类自身完成,还有多态,pHead As Object;Set pHead = New Node;Set pHead.pPrev = p;指向基类的指针指向了子类,并调用了子类的属性,是不是挺像C++的代码?



链表有了,二叉树,由临接表构成的图等数据结构都很容易实现了吧,实际上用VB能构造很复杂的数据结构,上面的代码只是简单的示例,实际可以做的更完善。



  另外,VB6也能够生成真实的地址。三种未正式公布的VBA方法VarPtr,ObjPtr,和StrPtr(实际上是指向运行DLL同一入口的三个不同的类型库别名)就可以用来建立指针,使用address=ObjPtr(Obj)就可以获得对象的地址,Obj为需要地址的对象,而Address为一个long型变量,其中放置了对象的地址,使用VarPtr(产生变量的地址和UDT),StrPtr(产生字符串的地址)和ObjPtr(产生对象的地址)可以构造真实的,非常复杂的数据结构。

  上面三个方法并没有在Microsoft的正式文档资料中公布(包括MSDN),但查看VB6的基本动态运行库MSVBVM60.DLL可以发现这三个方法:



[entry(0x60000006),hidden]

long __stdcall VarPtr([in]void* Ptr);

[entry(0x60000007),hidden]

long __stdcall StrPtr([in]BSTR Ptr);

[entry(0x60000008),hidden]

long __stdcall ObjPtr([in]IUnknown* Ptr);



  类似这样的隐藏方法还有不少,实际上VB6的功能是相当强大的,但大家又真正了解VB6多少呢?


2005年06月08日

晚饭时,潘玉荣说,他们那里有人去世,家人会给村里亲朋送一包包的茴香豆,叫“老人豆”。就是用蚕豆经过加工后的豆,很好吃。我知道绍兴的茴香豆是在鲁迅的《孔乙己》里,“窃书”人和茴香豆我都还有印象。

他说很好吃的时候,我见到他眼睛里的光。他连说了2次“很好吃”后,解释了一下是用什么豆做的,然后又说了2次“很好吃”。分明是诱惑我们。我叫他下次回家带些过来,满以为他会爽快答应,谁知他说:“不是什么好征兆啊!”。晕~

林峰问他,平时不死人时吃不吃的。他说也吃的。这不得了。我叫他下次回来之前,先在家找只蚊子或苍蝇(pest,拍死它,呵呵),拍死了,然后带包豆来给我们吃。

不知道下回有没有茴香豆吃。哦,不对,有没有老蚊子豆吃。。。

和恐龙说好了,这星期看一下编译原理,下个星期可以做UNIX的作业。

恐龙说,如果老师对上机结果不验收的话,就不去写编译器了,因为很难写。他算是诚实的了。我说,既然知道他的原理,就应该可以写得出来。我不是故意顶着他说话,我没有顶人家说话的习惯。我只是把我的想法说出来罢了。在我看来,知道了原理(也就是明确了方向和方法),只要努力去做,应该可以做成的。

还有我一直挂在脑子里的一句话:Anything anyone else has done ,you can probably do as well !