The Link Your Class | https://bbs.csdn.net/forums/MUEE308FZ |
---|---|
The Link of Requirement of This Assignment | https://bbs.csdn.net/topics/600798588 |
The Aim of This Assignment | Extract keywords of from the C or C++ code files |
MU STU ID and FZU STU ID | 19105461&831901312 |
The whole code in my Github:
https://github.com/ShuqiangWei/EE
Personal Software Process Stages | Estimated Time(minutes) | Completed Time(minutes) |
---|---|---|
Planning | - | - |
Estimate | 6 | 10 |
Development | - | - |
Analysis | 60 | 70 |
Design Spec | 60 | 75 |
Design Review | 40 | 45 |
Coding Standard | 40 | 40 |
Design | 30 | 30 |
Coding | 2000 | 2000 |
Code Review Planning | 120 | 110 |
Test | 50 | 30 |
Reporting | - | - |
Test Report | 60 | 60 |
Size Measurement | 30 | 30 |
Postmortem&Process Improvement | 60 | 30 |
Total | 2556 | 2530 |
Problem-solving ideas
Program Requirements
1.Basic requirement: output "keyword" statistics
2.Advanced requirement: output the number of "switch case" structures, and output the number of "case" corresponding to each group
3.Uplifting requirement: output the number of "if else" structures
4.Ultimate requirement: output the number of "if, else if, else" structures
Before completing the more difficult requirements, you need to complete the Lower requirements.
My minds
1.Read sample file
2.Write each of these levels as a function
3.Connect these functions in main function
I chose to write this program in C++ by Dec-C++, but the software has no functions in test coverage optimization and performance testing.
Design and implementation process
Read the file
The first and the most basic thing is read the file, but I can only read it line by line, which is not good for later operations, so after reading them, I store them in a vector.
function:
void file_read(string filename){
ifstream inFile;
string line;
inFile.open(filename.c_str());
if (!inFile.is_open()){
cout << "\nThe file was not successfully opened"
<< "\n Please check that the file currently exists."
<< endl;
exit(1);
} // check for successful open
while (getline(inFile, line)) {
file_content.push_back(line);
}
inFile.close(); //close the file
}
Delete the useless contents
To prevent the possible keywords in the comment statement and string from interfering with the extraction results, it is necessary to delete statements and strings in the comment.Here I learned and used the find() function and the copy substr() function.
function:
void delete_useless_content(){
string Line,words;
int index;
size_t tabs_location,annotation_location,quot_location,star1_location,star2_location;
for(int i=0;i<file_content.size(); i++){
Line=file_content[i];
if(Line.find("\t")!=Line.npos&&Line.find("\t")==0){
do{
tabs_location=Line.find("\t")+1;
Line=Line.substr(tabs_location,Line.length()-tabs_location);
}while(Line.find("\t") != Line.npos && Line.find("\t") == 0);
file_content[i] = Line;
}
if (Line.find("//") != Line.npos) {
annotation_location=Line.find("//");
if (annotation_location==0) {
file_content.erase(file_content.begin()+i);
i--;
} else {
words = Line.substr(0,annotation_location);
file_content[i] = words;
}
}else if(Line.find("\"") !=Line.npos){
size_t temp[50]={0};
tabs_location=0;
index=0;
while ((quot_location=Line.find("\"",tabs_location)) != Line.npos) {
temp[index]=quot_location;
index++;
tabs_location=quot_location+1;
}
temp[index]=Line.length();
words= Line.substr(0,temp[0]);
for (int j=1; temp[j]!=0; j+=2) {
words += Line.substr(temp[j]+1,temp[j+1]-temp[j]-1);
}
file_content[i]=words;
} else if(Line.find("/*") != Line.npos){
star1_location=Line.find("/*");
star2_location= Line.find("*/");
if (star2_location!= Line.npos) {
if (star1_location== 0) {
file_content[i] = Line.substr(star2_location+2,Line.length());
} else {
file_content[i] = Line.substr(0,star1_location);
}
i--;
}else{
file_content[i] = Line.substr(0,star1_location);
i += 1;
Line = file_content[i];
while (Line.find("*/") == Line.npos) {
file_content.erase(file_content.begin()+i);
Line = file_content[i];
}
star2_location = Line.find("*/")+2;
file_content[i] = Line.substr(star2_location,Line.length()-star2_location);
}
}
}
}
Judge keywords
function:
bool independence_judge(string line,long i){
if (line[i] < 48 || (line[i] > 57 && line[i] < 65) || (line[i] > 90 && line[i] < 97) ||line[i] >122) {
return true;
} else {
return false;
}
}
bool involve_judge(string line, string word){
size_t word_location;
word_location=line.find(word);
if (word_location == 0) {
if (independence_judge(line, word.length()) || word.length() == line.length()) {
return true;
} else {
return false;
}
} else {
if (independence_judge(line, word_location-1) && (independence_judge(line, word_location+word.length()) || word_location+word.length() == line.length())) {
return true;
} else {
return false;
}
}
}
Calculate the keywords number
void cal_keywords_num(){
int keywords_num=0;
string line;
for (int i = 0; i<file_content.size(); i++) {
line = file_content[i];
for (int j=0; j<32; j++) {
size_t keywords_location = line.find(keywords[j], 0);
while (keywords_location!=line.npos && involve_judge(line,keywords[j])) {
keywords_num++;
keywords_location = line.find(keywords[j],keywords_location + 1);
}
}
}
cout<<"total num: "<<keywords_num<<endl;
}
Calculate switch and case numbers
void cal_switch_case_num(){
int switch_num = 0,last = -1,case_num[200]={0};
string line;
for (int i = 0; i<file_content.size(); i++) {
line = file_content[i];
if (line.find("switch") != line.npos && involve_judge(line, "switch")) {
switch_num += 1;
last += 1;
}
if (line.find("case") != line.npos && involve_judge(line, "case")) { /*2é?òcase*/
case_num[last] += 1;
}
}
cout<<"switch num: "<<switch_num<<endl;
cout<<"case num:";
for (int j = 0; j<=last; j++) {
cout<<" "<<case_num[j];
}
cout<<endl;
}
Calculate if-else and if-elseif-else number
void cal_if_else_num(int level) {
int if_else_num = 0,if_elseif_else_num= 0;
stack<int> s;
string line;
for (int i = 0; i<file_content.size(); i++) {
line = file_content[i];
if (line.find("if") != line.npos && line.find("else") == line.npos && involve_judge(line, "if")) {
s.push(1);
} else if (line.find("if") == line.npos && line.find("else") != line.npos && s.empty() == false) {
if (s.top() == 1) {
if_else_num++;
} else {
if_elseif_else_num++;
}
s.pop();
}else if (line.find("if") != line.npos && line.find("else") != line.npos && involve_judge(line, "if")) {
s.push(2);
}
}
if (level == 3) {
cout<<"if-else num: "<<if_else_num<<endl;
} else if (level == 4) {
cout<<"if-else num: "<<if_else_num<<endl;
cout<<"if-else-if num: "<<if_elseif_else_num<<endl;
}
}
Unit test screenshots and description.
The program worked correctly.
performance optimization screenshots and descriptions
I tried several methods, but all failed. Because of the time problem, this experiment was not carried out this part.
In summary
In this experiment, I met many difficulties, including the formulation of methods in the early stage, these problems were solved by referring to other people's methods.The biggest regret is that I didn't learn how to test and optimize performance. I will try to learn this knowledge in the future.