福大软工1816 · 第二次作业
一、Fork的同名仓库的Github项目地址
二、PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 0 | 0 |
· Estimate | · 估计这个任务需要多少时间 | 300 | 360 |
Development | 开发 | 0 | 0 |
· Analysis | · 需求分析 (包括学习新技术) | 240 | 240 |
· Design Spec | · 生成设计文档 | 0 | 0 |
· Design Review | · 设计复审 | 0 | 0 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 0 | 0 |
· Design | · 具体设计 | 10 | |
· Coding | · 具体编码 | 80 | 80 |
· Code Review | · 代码复审 | 0 | 0 |
· Test | · 测试(自我测试,修改代码,提交修改) | 5 | 10 |
Reporting | 报告 | 60 | 120 |
· Test Repor | · 测试报告 | 0 | 0 |
· Size Measurement | · 计算工作量 | 10 | 10 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 10 | 10 |
三、解题思路描述
1.文本读入功能:在项目文件夹下创建的文本,利用fopen函数来读取文件。
2.字符统计功能:用fgetc来遍历文本,统计字符数。
3.行数统计功能:当有出现\n和用fgetc来遍历完文本时,行数+1。
4.单词统计功能:用一个ch=fgetc(fp)来记录当前的字符,并且用word=word+ch组成一个个单词,当单词的长度大于4的时候接着做一个循环来判断前四个字符必须为字母。
5.频率排序功能:把map赋值给vec,用写好的两个结构体用对vec进行字典顺序的排序和频率的排序(我先进行了字典顺序的排序再进行频率的排序,后来发现字典顺序的排序有问题但来不及改了)。
6.文本写入功能:通过fopen,fwrite自动创建一个result文本,并将需要的功能写入result文本。
四、设计实现过程
*gets():用于读取test.txt文件
- 在while((ch=fgetc(fp))!=EOF) 循环中统计单词数行数,并进行大写转小写,并把单词和出现次数统计到map中
- sort():用于排序前十词频数
五、代码测试
- 读取的文本与程序放在同个文件夹
- 代码执行后创建result文本
六、性能分析
消耗最大的函数
七、代码
1.读取文件
FILE *fp;
gets_s(filename);
errno_t err;
err = fopen_s(&fp, filename, "r");
2.统计字符数,判断能否构成单词,统计单词数,统计行数,大小写转换
while (!feof(fp))fgetc(fp) && num++;//统计字符数
rewind(fp);//重新开始读取文件
while ((ch = fgetc(fp)) != EOF)//当ch不是最后一个字符时开始进入循环
{
if ((ch >= 48 && ch <= 57) || (ch >= 65 && ch <= 90) || (ch >= 97 && ch <= 122))
word = word + ch;//当字符是数字或者字母时,用word拼在一起
else
{
if (word.length() >= 4)
{
for (i = 0; i < 4; i++)
if (!(((word[i] >= 65) && (word[i] <= 90)) || ((word[i] >= 97) && (word[i] <= 122))))
break;//判断前四个为字母
if (i >= 4)
{
for (j = 0; j < word.length(); j++)
if (word[j] >= 65 && word[j] <= 90)
word[j] = word[j] + 32;//大写字母转换成小写字母
wordcount++;//行数+1
it = m.find(word);
if (it == m.end())
m.insert(pair<string, int>(word, 1));//当单词没出现在map中时,记录进去
else
it->second++;//单词出现过时,value值+1
}
}
word.erase();//清空word
if (ch == '\n')
linecount++;//换行时,行数+1
}
}
linecount++;//结束时,行数+1
3.单词出现的频率排序
typedef pair<string, int> PAIR;
struct cmp
{
bool operator()(const PAIR& lhs, const PAIR& rhs)
{
return lhs.second < rhs.second;
}
};//用于排序频次
struct comp
{
bool operator()(const PAIR& lhs, const PAIR& rhs)
{
return lhs.first > rhs.first;
}
};//用于排序字典顺序
vector<PAIR>vec(m.begin(), m.end());//把map赋值给vector
sort(vec.begin(), vec.end(), comp());//字典顺序排序
sort(vec.begin(), vec.end(), cmp());//频次排序
3.写入文件
FILE *fp2;
errno_t err2;
err2 = fopen_s(&fp2, "result.txt", "w");
fwrite(res_c, res.length(), 1, fp2);
八、异常处理
有把输出的字符开的太小了导致输出文件时出现乱码,一开始把代码写在dev,然后复制到vs中,也出现了挺多的问题。还有各种各样的问题。