我的程序(2):c源码统计器

来源:互联网 发布:php addslashes() 编辑:程序博客网 时间:2024/04/30 17:52

我的程序(2):c源码统计器

这是大二时数据结构的课程设计,要求用vc做一个有用户界面的程序.因为当时还不会用vc,所以在去年寒假用c写了一个没有界面的源码统计器,就算是课程设计的内核吧.

期间又该了多次,添加一些功能,增强安全性,对代码进行优化等,总共又5个版本.贴出来几个有代表性的,希望大家指正.

0.0  :在键盘上输入程序,然后程序返回结果.

                      /*统计c中代码行和注释行的数量*/

#include<stdio.h>

 

void recomment(int c,int *pzhushi,int *phangshu,int *flagzhushi,int *flagzhw);

void in_comment(int *pzhushi,int *phangshu, int *flagzhushi,int *flagzhw);

void echo_quote(int c);

 

main()

{

int c;

    int nzhushi=0, nhangshu=0;   /* 记录注释和总行数*/

    int *pzhushi=&nzhushi;

    int *phangshu=&nhangshu;

    int *flagzhushi, *flagzhw;  /*标志:是否在注释或代码中*/

    *flagzhushi=0,  *flagzhw=0;

 

 

    while( (c=getchar())!=EOF )

        recomment(c,pzhushi,phangshu,flagzhushi,flagzhw);

 

    printf("%d,%d/n",*pzhushi,*phangshu);

    getch();

    return 0;

}   /*主函数完成*/

           

 

 

void recomment(int c,int *pzhushi,int *phangshu,int *flagzhushi,int *flagzhw)

{

 

     int d;

    if (c == '/'){

        if ( (d=getchar()) =='*' )

            in_comment(pzhushi,phangshu,flagzhushi,flagzhw);/* 进入注释处理函数*/

        else if ( d == '/' )

            recomment(d,pzhushi,phangshu,flagzhushi,flagzhw); /*递归*/

    }

 

    else if ( c == '/'' || c == '"' )

        echo_quote(c);                  /* 在引号内的注释不算*/

    else if ( c == '/n'){               /* 对回车的处理(考虑了各种情况)*/

        if(*flagzhushi == 1 )           /*如果此行有注释*/

            ++ (*pzhushi);

        if ( *flagzhw==1 )

            ++ (*phangshu);

        *flagzhw=*flagzhushi=0;

    }else if ( *flagzhw == 0 && c !=' ' )

        *flagzhw=1;

}   /*完成*/

            

 

void in_comment(int *pzhushi,int *phangshu, int *flagzhushi,int *flagzhw)

{

 

    int c,d;

 

    c=getchar();

    d=getchar();

    while ( c != '*' || d != '/' ){

        if ( c == '/n' ){

            ++ (*pzhushi);

            if ( *flagzhw == 1 )

                ++ (*phangshu);

        }

        c=d;

        d=getchar();

    }

    *flagzhushi=1;

}  /* 完成*/

 

 

 

void echo_quote(int c) 

{

    int d;

    while ( (d=getchar()) !=c )

        if ( d=='//')

            getchar();              /*忽略转义字符*/

}    /*完成*/

 

1.0    主要对0.0版本中复杂的函数参数进行了修改,用一个结构指针解决问题.(谢谢csdn上面的朋友的指点)

/*统计c中代码行和注释行的数量*/

#include<stdio.h>

 

 struct fun{

     int ncomment;

     int ncode;

     int flagcomment;

     int flagcode;

 }a;

 struct fun *p=&a;

 

 

 

 

void recomment(int c,struct fun *p);

void in_comment(struct fun *p);

void echo_quote(int c);

 

main()

{

 

 

    int c;

 

 

    while( (c=getchar())!=EOF )

        recomment(c,p);

 

    printf("%d,%d/n",p->ncomment,p->ncode);

     getch();

    return 0;

}   /*主函数完成*/

           

 

 

 

 

    

void recomment(int c,struct fun *p)

{

 

     int d;

    if (c == '/'){

        if ( (d=getchar()) =='*' )

            in_comment(p);/* 进入注释处理函数*/

        else if ( d == '/' )

            recomment(d,p); /*递归*/

    }

 

    else if ( c == '/'' || c == '"' )

        echo_quote(c);                  /* 在引号内的注释不算*/

    else if ( c == '/n'){               /* 对回车的处理(考虑了各种情况)*/

        if(p->flagcomment == 1 )           /*此行有注释*/

            ++ (p->ncomment);

        if ( p->flagcode==1 )

            ++ (p->ncode);

        p->flagcode=p->flagcomment=0;

    }else if ( p->flagcode == 0 && c !=' ' )

       p->flagcode=1;

}   /*完成*/

           

 

void in_comment(struct fun *p)

{

 

    int c,d;

 

    c=getchar();

    d=getchar();

    while ( c != '*' || d != '/' ){

        if ( c == '/n' ){

            ++ (p->ncomment);

            if ( p->flagcode == 1 )

                ++ (p->ncode);

        }

        c=d;

        d=getchar();

    }

   p->flagcomment=1;

}  /* 完成*/

 

 

 

void echo_quote(int c) 

{

    int d;

    while ( (d=getchar()) !=c )

        if ( d=='//')

            getchar();              /*忽略转义字符*/

}    /*完成*/

 

3.0版本    不再由键盘输入程序,输入程序的路径即可.(但反斜杠问题没有解决0

/*统计c中代码行和注释行的数量*/

#include<stdio.h>

#include<stdlib.h>

 

 struct fun{

     int ncomment;

     int ncode;

     int flagcomment;

     int flagcode;

      FILE *pf;

 }a = {0,0,0,0,NULL};

 struct fun *p=&a;

 

 

 

 

void recomment(int c,struct fun *p);

void in_comment(struct fun *p);

void echo_quote(int c,struct fun *p);

 

main()

{

    int c;

     char s[50];

    

    printf("input the path of the file(注意;当输入反斜杠时,请连续输入两个)这个问题将在下一版中解决/n");

     scanf("%s",s);

   

    p->pf = fopen(s,"r");

    if( p->pf == NULL ){

        printf("open fail!/n");

        exit(0);

    }

 

    while( ( c=fgetc(p->pf) ) != EOF )

        recomment(c,p);

 

    printf("%d,%d/n",p->ncomment,p->ncode);

    fclose(p->pf);

    return 0;

}   /*主函数完成*/

           

 

 

 

 

void recomment(int c,struct fun *p)

{

 

     int d;

    if (c == '/'){

        if ( (d=fgetc(p->pf)) =='*' )

            in_comment(p);/* 进入注释处理函数*/

        else if ( d == '/' )

            recomment(d,p); /*递归*/

    }

 

    else if ( c == '/'' || c == '"' )

        echo_quote(c,p);                  /* 在引号内的注释不算*/

    else if ( c == '/n'){               /* 对回车的处理(考虑了各种情况)*/

        if(p->flagcomment == 1 )           /*此行有注释*/

            ++ (p->ncomment);

        if ( p->flagcode==1 )

            ++ (p->ncode);

        p->flagcode=p->flagcomment=0;

    }else if ( p->flagcode == 0 && c !=' ' )

       p->flagcode=1;

}   /*完成*/

           

 

void in_comment(struct fun *p)

{

 

    int c,d;

 

    c=fgetc(p->pf);

    d=fgetc(p->pf);

    while ( c != '*' || d != '/' ){

        if ( c == '/n' ){

            ++ (p->ncomment);

            if ( p->flagcode == 1 )

                ++ (p->ncode);

        }

        c=d;

        d=fgetc(p->pf);

    }

   p->flagcomment=1;

}  /* 完成*/

 

 

 

void echo_quote(int c,struct fun *p) 

 

{

    int d;

    while ( (d=fgetc(p->pf)) !=c )

        if ( d=='//')

            fgetc(p->pf);              /*忽略转义字符*/

}    /*完成*/

 

4.0版本 (最终版本)  可以直接输入程序的路径

/*统计c中代码行(不包括空白行)和注释行的数量*/

#include<stdio.h>

#include<stdlib.h>

 

 struct fun{

     int ncomment;

     int ncode;

     int flagcomment;

     int flagcode;

      FILE *pf;

 }a = {0,0,0,0,NULL};

 struct fun *p=&a;

 

 

void recomment(int c,struct fun *p);

void in_comment(struct fun *p);

void echo_quote(int c,struct fun *p);

char * change(char *ps,char *pt);      /*处理路径中的反斜杠问题。因为在字符串中要用//表示/ */

 

 

main()

{

    int c;

     char s[50];

     char t[100];

     char *ps = s;

     char *pt = t;

 

     printf("input the path of the file/n");

     scanf("%s",s);

 

    p->pf = fopen( change(ps,pt),"r" );     /*打开文件*/

    if( p->pf == NULL ){                   /*输入的文件路径不对或文件不存在*/

        printf("open fail!/n");

        exit(0);

    }                                   

    while( ( c = fgetc(p->pf) ) != EOF )

        recomment(c,p);

 

    printf("the commend lines are %d/n,the all code lines(not include black lines) are %d/n",p->ncomment,p->ncode);

    fclose(p->pf);                      /*关闭文件*/

    return 0;                                

}   /*主函数完成*/

           

 

 

 

 

void recomment(int c,struct fun *p)

{

 

     int d;

    if (c == '/'){

        if ( (d = fgetc(p->pf)) =='*' )

            in_comment(p);/* 进入注释处理函数*/

        else if ( d == '/' )

            recomment(d,p); /*递归*/

    }

 

    else if ( c == '/'' || c == '"' )

        echo_quote(c,p);                  /* 在引号内的注释不算*/

    else if ( c == '/n'){               /* 对回车的处理(考虑了各种情况)*/

        if(p->flagcomment == 1 )           /*如果此行有注释*/

            ++ (p->ncomment);

        if ( p->flagcode == 1 )            /*如果此行有代码*/

            ++ (p->ncode);

        p->flagcode = p->flagcomment = 0;     /*把标志复位*/

    }else if ( p->flagcode == 0 && c != ' ' )

       p->flagcode = 1;

}   /*完成*/

           

 

void in_comment(struct fun *p)      /*寻找注释结束的地方*/

{

 

    int c,d;

 

    c = fgetc(p->pf);

    d = fgetc(p->pf);

    while ( c != '*' || d != '/' ){

        if ( c == '/n' ){

            ++ (p->ncomment);

            if ( p->flagcode == 1 )

                ++ (p->ncode);

        }

        c = d;

        d = fgetc(p->pf);

    }

   p->flagcomment = 1;

}  /* 完成*/

 

 

 

void echo_quote(int c,struct fun *p) 

 

{

    int d;

    while ( (d = fgetc(p->pf)) !=c )

        if ( d == '//')

            fgetc(p->pf);              /*忽略转义字符*/

}    /*完成*/

 

 

char * change(char *ps,char *pt)     /*处理反斜杠的问题*/

{

     char *p = pt;

     char c;

 

     while( (c = *pt++ = *ps++) != '/0' )

         if( c == '//' )

              *pt = '//';

     return p;

}