结对项目小组成员:1120161896 石成豪 1120161889 付文桢
1) Github地址:
https://github.com/ChengHaoShi/our_wordcount
2) PSP表格
PSP2.1 |
Personal Software Process Stages |
预计耗时(分钟) |
实际耗时(分钟) |
Planning |
计划 |
30 |
20 |
· Estimate |
·估计这个任务需要多少时间 |
30 |
20 |
Development |
开发 |
520 |
500 |
· Analysis |
·需求分析(包括学习新技术) |
70 |
50 |
· Design Spec |
·生成设计文档 |
60 |
50 |
·Design Review |
·设计复审(和同事审核设计文档) |
30 |
40 |
· Coding Standard |
·代码规范 |
20 |
25 |
· Design |
·具体设计 |
50 |
55 |
· Coding |
·具体编码 |
150 |
130 |
· Code Review |
·代码复审 |
50 |
60 |
· Test |
·测试(自我测试,修改代码, 提交修改) |
90 |
100 |
Reporting |
报告 |
150 |
130 |
· Test Report |
·测试报告 |
40 |
30 |
· Size Measurement |
·计算工作量 |
50 |
50 |
· Postmortem & Process Improvement Plan |
·事后总结,并提出过程改进计划 |
60 |
50 |
合计 |
700 |
650 |
3)解题思路
题目要求:
根据题(wordcount)中所做要求,程序应实现以下功能:
1返回文件的字符数
2返回文件的词的数目
3返回文件的行数
扩展功能:
4返回文件代码行数
5返回文件空行数
6返回文件注释行数
高级功能(能力有限。。。。。。)
4)设计实现过程
采用<fsteam>头文件,用open函数来打开文件,用基本的c语言结构体来储存单词出现次数,用数组来标记该字符是否出现,每次从txt文件中读出一行用 line数组来接收,并统计计算出代码行、空行、和计数行。(由于程序较短,并没有封装)。
5)程序使用方法
用open函数读取WORDCOUNT.txt 并用数组 line 来逐行读取分析统计并计数。
程序运行图:
性能分析图:
6)核心代码
1 #include <iostream> 2 #include <fstream> 3 #include <string> 4 #define MAX 10000 5 using namespace std; 6 typedef struct m 7 { 8 char word[50]; 9 }NODE; 10 int main(int argc, char * argv[]) 11 { 12 NODE all_word[MAX];//计算单词的出现 13 int i_all_word = 0; 14 string line = ""; 15 ifstream ifs; 16 char filename[80]; 17 printf("请输入文件路径:\n"); 18 scanf("%s", filename); 19 ifs.open(filename); 20 if (!ifs) 21 { 22 cout << "文件打开失败" << endl; 23 exit(0); 24 } 25 int mark_asc[260];//标记出现的字符 26 int count_asc = 0;//记录个数 27 memset(mark_asc, 0, sizeof(mark_asc)); 28 ////////////////////////////////////////////// 29 //标记:双引号 斜杠星 函数 代码 注释 30 int bSyh = 0, bXgx = 0, bHs = -1, bCode = 0, bZs = 0; 31 // "" '' // /* {} 32 ///////////////////////////////////////////// 33 //个数:空行 注释 代码 公共 函数 34 int i, empty_l = 0, notes = 0, code = 0, public_l = 0, funct = 0; 35 // 36 while (!ifs.eof()) 37 { 38 i = 0; 39 getline(ifs, line); //读取一行文件 40 bCode = 0; //该行没有代码 41 bZs = 0; //该行没有注释 42 if (bXgx) //bXgx 斜杠星注释标记 43 bZs = 1; //该行有注释 44 //过滤无效符号 45 for (int i1 = 0; i1 < size(line); i1++)//统计字符出现个数 46 { 47 if (mark_asc[int(line[i1])] == 0) 48 { 49 count_asc++; 50 mark_asc[int(line[i1])] = 1; 51 } 52 } 53 for (int i2 = 0; i2 < size(line); i2++)//检查这一行的单词 54 { 55 char now_word[50]; 56 memset(now_word, 0, sizeof(now_word)); 57 int count_now_word = 0; 58 if ((line[i2] <= 90 && line[i2] >= 65) || (line[i2] <= 122 && line[i2] >= 97))//找到字母 59 { 60 for (int i3 = i2; i3 < size(line); i3++) 61 { 62 now_word[count_now_word] = line[i3]; 63 count_now_word++; 64 if (i3 + 1 == size(line) || !((line[i3 + 1] <= 90 && line[i3 + 1] >= 65) || (line[i3 + 1] <= 122 && line[i3 + 1] >= 97)))//找到非字母停止 65 { 66 i2 = i3 + 1; 67 now_word[count_now_word] = 0; 68 //cout << now_word << endl; 69 int judge = 1; 70 for (int i4 = 0; i4 < i_all_word; i4++)//判断该单词是否出现过 71 { 72 if (strcmp(now_word, all_word[i4].word) == 0) 73 { 74 judge = 0; 75 break; 76 } 77 } 78 if (judge == 1)//没出现过就加入 79 { 80 strcpy(all_word[i_all_word].word, now_word); 81 i_all_word++; 82 } 83 memset(now_word, 0, sizeof(now_word));//每找到一个单词后清空 84 count_now_word = 0; 85 break; 86 } 87 } 88 89 } 90 } 91 while (line[i] == ' ' || line[i] == '\t' || line[i] == '\r' || line[i] == '\n') 92 { 93 ++i; 94 } 95 //“以下为空行统计区域:开始” 96 if (!bXgx && line[i] == '\0') //空行 97 { 98 ++empty_l; 99 continue; 100 } 101 //“空行统计:结束” 102 while (1) 103 { 104 //第一次遇到双引号 引号为非转义字符(\") 105 if (!bSyh && line[i] == '\"' && ((i > 0 && line[i - 1] != '\\') || (i == 0))) 106 { 107 ++i; 108 bSyh = 1; 109 continue; 110 } 111 //“正在进行双引号屏蔽....” 112 if (bSyh) 113 { 114 //“ \”结束” 115 if (line[i] == '\"' && ((i > 0 && line[i - 1] != '\\') || (i == 0))) 116 { 117 bSyh = 0; 118 } 119 else if (line[i] == '\0') //行末尾 120 { 121 if (bZs) 122 ++notes; 123 if (bCode) 124 ++code; 125 if (bZs && bCode) 126 ++public_l; 127 break; 128 } 129 ++i; 130 continue; 131 } 132 //遇到单引号(避免'{','}'),且非转义字符\',连续跳过3个(第二个'后位置) 133 if (line[i] == '\'' && ((i > 0 && line[i - 1] != '\\') || (i == 0))) 134 { 135 i += 3; 136 continue; 137 } 138 //“//注释行” 139 if (!bXgx && line[i] == '/' && line[i + 1] == '/') 140 { 141 if (bCode) //“前有代码,混合注释行” 142 { 143 ++notes; //注释 144 ++code; //代码 145 ++public_l; //公共 146 } 147 else //纯注释行 148 { 149 ++notes; 150 } 151 break; //跳出当前行(即,内while循环),“//”后代码不做判断 152 } 153 //“/*注释开始” 154 if (!bXgx && line[i] == '/' && line[i + 1] == '*') 155 { 156 i += 2; //跳过/*符号 157 bXgx = 1; //标记“/*”开始 158 bZs = 1; //“发现注释” 159 continue; 160 } 161 //“正在进行多行注释....” 162 if (bXgx) 163 { 164 //“*/注释结束” 165 if (line[i] == '*' && line[i + 1] == '/') 166 { 167 ++i; //“跳过*/”注意后有一个 ++i; 168 bXgx = 0; 169 } 170 else if (line[i] == '\0') //行末尾 171 { 172 if (bCode) //注释前有代码,即“混合行” 173 { 174 ++code; 175 ++notes; 176 ++public_l; 177 } 178 else 179 { 180 ++notes; //“纯注释” 181 } 182 break; 183 } 184 ++i; 185 continue; 186 } 187 if (line[i] == '\0') 188 { 189 if (bZs) 190 ++notes; 191 if (bCode) 192 ++code; 193 if (bZs && bCode) 194 ++public_l; 195 break; 196 } 197 //“以下全是有效代码区域” 198 //“函数个数统计区域:开始” 199 if (line[i] == '{') //记录函数左括号 200 { 201 ++bHs; 202 } 203 else if (line[i] == '}') //遇到函数右括号 204 { 205 if (bHs == 0) //“发现一个函数” 206 ++funct; 207 --bHs; 208 } 209 //“函数统计:结束” 210 ++i; 211 bCode = 1; //能执行到这里,说明该行存在代码 212 } 213 } 214 printf("请输入想查询的数据\n"); 215 while (1) 216 { 217 string trr; 218 cin >> trr; 219 if ("-c" == trr) 220 { 221 cout << "字符:" << count_asc << endl; 222 } 223 else if ("-w" == trr) 224 { 225 cout << "单词:" << i_all_word << endl; 226 } 227 else if ("-a" == trr) 228 { 229 cout << "代码: " << code << endl; 230 cout << "空行: " << empty_l << endl; 231 cout << "注释: " << notes << endl; 232 cout << "公共: " << public_l << endl; 233 cout << "函数: " << funct << endl; 234 } 235 else if ("break" == trr) 236 { 237 break; 238 } 239 } 240 return 0; 241 }