github传送门:https://github.com/Bubblegod/BB
一、项目要求
wc.exe 是一个常见的工具,它能统计文本文件的字符数、单词数和行数。这个项目要求写一个命令行程序,模仿已有wc.exe 的功能,并加以扩充,给出某程序设计语言源文件的字符数、单词数和行数。
实现一个统计程序,它能正确统计程序文件中的字符数、单词数、行数,以及还具备其他扩展功能,并能够快速地处理多个文件。
具体功能要求:
程序处理用户需求的模式为:
wc.exe [parameter] [file_name]
基本功能列表:
wc.exe -c file.c //返回文件 file.c 的字符数 (实现)
wc.exe -w file.c //返回文件 file.c 的词的数目 (实现)
wc.exe -l file.c //返回文件 file.c 的行数 (实现)
扩展功能
-s 递归处理目录下符合条件的文件。
-a 返回更复杂的数据(代码行 / 空行 / 注释行)
-s -c/-w/-l/-a *.cpp/txt/.. 返回当前文件夹里面所有符合条件的文件的相对应信息,若无第二个参数,则返回所有符合文件的文件名的路径
二、PSP2.1表格
PSP2.1 |
Personal Software Process Stages |
预估耗时(分钟) |
实际耗时(分钟) |
Planning |
计划 |
20 |
30 |
Estimate |
估计这个任务需要多少时间 |
10 |
10 |
Development |
开发 |
360 |
480 |
Analysis |
需求分析 (包括学习新技术) |
120 |
180 |
Design Spec |
生成设计文档 |
20 |
20 |
Design Review |
设计复审 (和同事审核设计文档) |
10 |
10 |
Coding Standard |
代码规范 (为目前的开发制定合适的规范) |
10 |
10 |
Design |
具体设计 |
100 |
90 |
Coding |
具体编码 |
200 |
300 |
Code Review |
代码复审 |
60 |
60 |
Test |
测试(自我测试,修改代码,提交修改) |
120 |
100 |
Reporting |
报告 |
20 |
30 |
Test Report |
测试报告 |
20 |
30 |
Size Measurement |
计算工作量 |
20 |
20 |
Postmortem & Process Improvement Plan |
事后总结, 并提出过程改进计划 |
20 |
30 |
合计 |
1110 |
1400 |
三、基本功能主要实现的代码:
-l功能的实现代码
使用getline函数读取文件里的字符串,逐行逐行读取并储存在line变量里面,每读取一行,count变量便++;
int l_function(char address[]){ //the function to statistic the number of line in the whole file string line; int count; count=0; ifstream in(address); if(NULL!=in){ while(getline(in,line)){ count++; } } if(line=="") count++; //if the end of line is empty, still should be regarded as a line, but I need to count it manually return count; }
-c功能的实现代码
计算整个文件字符的长度,并计算空格数还有换行符数,用文件字符的长度减去计算空格数还有换行符数,便是字符的个数。
int c_function(int line){ return filetext.length()-line; //the number of the charaters equals the length of the filetext minus the number of lines }
-w功能的实现代码
连续使用while循环,如果当前i下标指向有效的字符,就找到下一个无效字符的位置,反之也如此,每找到一个无效字符的下标,wordcount便++。
int w_function(){ //the function of counting the number of words int i,wordcount=0; i=0; if(!word_judgment(filetext[0])){ while(!word_judgment(filetext[i])){ i++; } } //locate the first word in the whole string while(i<filetext.length()){ while(word_judgment(filetext[i])){ i++; } wordcount++; //locate the charater that before a word in the whole string while(!word_judgment(filetext[i])){ i++; } } return wordcount; }
-a功能的实现
分类讨论,使用getline函数,逐行逐行读取文件里面的数据,如果只有一个可显示的字符,blankNum变量就++,否则的话,便寻找”//”的位置,如果”//”的位置在一开头(前面全是空格除外),commNum变量就++,如果”//”不在开头或者不存在,则是代码行,codeNum++;
void a_function(char address[]){ int count; int blankNum=0,comNum=0,codeNum=0; string line; ifstream in(address); if(NULL!=in){ while(getline(in,line)){ count=0; for(int i=0;i<line.length();i++){ if(line[i]!=' '&&line[i]!='\n') count++; } if(count<=1){ blankNum++; } else{ int i,pos=-1; for(i=0;i<line.length()-1;i++){ if((line[i]=='/')&&(line[i+1]=='/')) pos=i; } count=0; if(pos!=-1){ for(i=0;i<pos;i++){ if(line[i]!=' '&&line[i]!='\n') count++; } if(count<=1){ comNum++; } else codeNum++; } else codeNum++; } } } cout<<"blankNum="<<blankNum<<endl<<"codeNum="<<codeNum<<endl<<"comNum="<<comNum<<endl; }
-x功能的实现
采用MFC图形界面设计来实现设计图像化窗口的功能。
采用图形化编程来设计我想要的界面,把想使用的控件直接拖进程序文件里面,窗口界面设计的排版便完成了。
之后右击控件->添加变量,输入变量名字,就相当于在cpp文件里面定义了一个按钮控件的变量,之后能在cpp文件里面进行相关的操作。
Browse按钮的功能实现
Browse按钮的功能是浏览文件路径,并且复制文件路径到指定的空白处。
void CWordsCountDlg::OnBnClickedButton1() { // TODO: 在此添加控件通知处理程序代码 TCHAR szBuffer[MAX_PATH] = { 0 }; OPENFILENAME ofn = { 0 }; ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = m_hWnd; ofn.lpstrFilter = _T("c*文件(*.c*)\0*.c*\0txt文件(*.txt)\0*.txt\0所有文件(*.*)\0*.*\0");//要选择的文件后缀 ofn.lpstrInitialDir = _T("D:\\");//默认的文件路径 ofn.lpstrFile = szBuffer;//存放文件的缓冲区 ofn.nMaxFile = sizeof(szBuffer) / sizeof(*szBuffer); ofn.nFilterIndex = 0; ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER;//标志如果是多选要加上OFN_ALLOWMULTISELECT BOOL bSel = GetOpenFileName(&ofn); m_editbrowse.SetWindowTextW(szBuffer); statistic sta; address = sta.transition(szBuffer); }
Begin按钮的功能实现
按钮响应事件是进行各个功能的统计,并显示在指定的空白处。
void CWordsCountDlg::OnBnClickedButtonbegin() { // TODO: 在此添加控件通知处理程序代码 statistic ss(address); CString str; LPCTSTR pStr = LPCTSTR(str); ss.fileinit(address); str.Format(_T("%d"), ss.getcharater()); pStr = LPCTSTR(str); m_editchar.SetWindowTextW(pStr); str.Format(_T("%d"), ss.getword()); pStr = LPCTSTR(str); m_word.SetWindowTextW(pStr); str.Format(_T("%d"), ss.getlines()); pStr = LPCTSTR(str); m_editline.SetWindowTextW(pStr); str.Format(_T("%d"), ss.getblank()); pStr = LPCTSTR(str); m_editblank.SetWindowTextW(pStr); str.Format(_T("%d"), ss.getcode()); pStr = LPCTSTR(str); m_editcode.SetWindowTextW(pStr); str.Format(_T("%d"), ss.getcomment()); pStr = LPCTSTR(str); m_editecomm.SetWindowTextW(pStr); }
四、代码测试
进行测试的样本文本
1-基本功能与拓展功能的测试
2-高级功能的测试
五、小结
1.通过对这一课题的设计和实现,我对 Visial C++环境进行了深一步的了解,并逐渐开始熟练 Visial C++环境的工作界面。并认识到,熟悉这些快捷键,极为便捷编写程序,但是还要更加熟悉。
2.基本功不够,有些函数表达地不够精通,一些函数需要上网查资料来表达,导致了耗时比较多,要多多改进。