一个简单的统计代码行数的程序(基于MFC)

       从上次写日志,也就是定了工作之后,又玩了几天,就开始看这学期子目录的开的课程,以备期末考试,有51单片机,数据库原理,软件工程,电子商务4门。单片机的老师没认真给我们上课,我们也没认真学,教材很不合理,考试又是开卷,直接胡乱应付了下。数据库看得还可以,明白了不少的数据库原理,原来设计一个数据库的表单有那么多道理,还有,实际的操作也做了一些,过些日子我打算写一个使用数据库的×××管理系统之类的东西来练练手。软件工程老师非常SB,估计要挂。电子商务没上过多少课,最后抄了个同学的实验报告,电子商务讲得什么EDI,XML之类的临时看了下去考了试,好在考试是开卷,考得还可以,最后写XML及相应DTD,也写出来了。算了,闲话就说这么多了,总之差不多一个月就在干这么些乱七八糟的事情。这几天总算静下心来把一直想做的统计我这4年写了多少代码的程序写了出来。因为我的所有代码都按类别放在不同的文件夹中,我只需要做一个可以遍历目录以及子目录的程序然后做判断,逐个打开后缀名为.cpp,.c,.h,.asm,.java的文件再数其中的回车符的个数,做累加就OK了。而这个根文件夹的定位由一个系统提供的对话框来实现,用鼠标直接定位就可以了。下面是整个过程:


1:建立基于对话框的应用程序,可由app wizard直接生成。
2:按以上界面做相应控件的布局。
3:静态文本框直接放入。
4:为Browse左边的EDIT控件设置属性为Styles ReadOnly,这个框是要显示用户定位的根文件夹的路径的,因为我们的定位不需要用户直接键入,所以设为ReadOnly。然后用ClassWizard为该控件关联一个CEdit型变量m_Path,因为我们要用它来控件这个EDIT控件的行为。
5:为Browse按钮关联代码,以便当用户按下它时弹出一个选择根文件夹的系统对话框。仍然可以用ClassWizard做。把下面的代码粘到ToDo:下面

char path[100]={'/0'};
BROWSEINFO lpbi={0,NULL,NULL,"Choose the folder that your source files in:",0,NULL,0,0};
::SHGetPathFromIDList((::SHBrowseForFolder(&lpbi)),(LPTSTR)path);
if(*path!='/0')
{
 m_Path.SetSel(0,-1);
 m_Path.ReplaceSel(path);
}
m_sPath=path;
/
其中SHBrowseForFolder是一个API函数,lpbi是一个系统定义的结构,专用于此的。其中第4个参数是显示在弹出对话框上部的标题,::SHGetPathFromIDList用于从::SHBrowseForFolder返回的结构中提取完整目录放到path中。然后用最后这个值被存放在事先定义有对话框类中的CString 型变量 CString m_sPath中,以备后用。
6:用ClassWizard为复选框.cpp,.c,.h,.asm,.java关联变量,分别为BOOL型的m_Cpp,m_C,m_H,m_Asm,m_Java。它们用来检验哪种类型的文件是要统计的。
7:为The result is :及lines!之间的EDIT控件关联变量m_Result,控制该控件显示最后的结果。
8:为Go->按钮关联代码:
void CCodeLinesDlg::OnGo()
{
 UpdateData(TRUE);
 if(m_sPath.IsEmpty())
 {
  MessageBox("You haven't input the path or use Browse button locate the location!");
  return;
 }
 if(m_iResult!=0)
 {
  m_iResult=0;
 }
 mCount(m_sPath);
 CString result;
 result.Format("%d",m_iResult);
 m_Result.SetSel(0,-1);
 m_Result.ReplaceSel(result);
 return;
}


void CCodeLinesDlg::mCount(CString sPath)
{
 if(sPath.Right(1)!="//")
  sPath+= "//";
 sPath+= "*.*";
 CFileFind finder;
 BOOL bWorking=finder.FindFile(sPath);
 while(bWorking)
 {
  bWorking=finder.FindNextFile();
  CString subDirectory=finder.GetFilePath();
  if(finder.IsDirectory() && !finder.IsDots())
  {  
   mCount(subDirectory);
  }  
  else if(!finder.IsDirectory() && !finder.IsDots())
  {
   CString file=finder.GetFilePath(); 
   if((!file.Right(4).Compare(".cpp")&&m_Cpp) || (!file.Right(2).Compare(".c")&&m_H) || (!file.Right(2).Compare(".h")&&m_H) || (!file.Right(4).Compare(".asm")&&m_Asm) || (!file.Right(5).Compare(".java")&&m_Java))
   {
    FILE* fp;
    if((fp=fopen(LPCTSTR(file),"r"))==NULL)
    {
     AfxMessageBox(file);
     AfxMessageBox("Open file error!");
    }
    else
    {
     int c;
     while((c=getc(fp))!=EOF)
     {
      if(c=='/n')
      {
       m_iResult++;
      }
     }
     fclose(fp);
    }
   }
  }
 }
}
m_Count这个函数的声明要自己放在类中的相应合适位置。OnGo中的 UpdateData(TRUE);是根据所有控件的当前状态更新相关联的各个变量。要没有这句,即使你选中了.cpp框的勾,系统还认为当前m_Cpp的值是false。随后检测了是否位了根文件夹位置,m_iResult是在本类中定义的一个整型变量,用来存储统计结果,检测它是否非0,是为了防止用户第二次点Go->按钮会将前一次的统计结果加上去。然后调用m_Count函数就可以了。其中的递归查询各文件还是有点复杂。最后将结果放在m_iResult中,并用m_Result控件显示给用户。
9:为Exit控件关联代码:
很简单,一个OnOK()函数调用即可关闭整个对话框。
就这样子啦,最后我的统计是49911行,唉,还不到5万行,真失败。下面我打算把这个程序的界面搞靓一点。再说 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值