个人队友和我同样选取了C++来实现我的项目,其中主要包括注册,产生,文件输出三部分,各有优缺点,咱们来仔细的看一看代码的优缺点。数据库
能够看到,个人队友首先对全部的函数均进行了声明,这是一个很好的习惯,能够避免在以后的函数调用中不因次序问题而出现调用错误。数组
2.1 entry()安全
1 int entry(string a) 2 { 3 name_1 += "C:\\Users\\Asus\\Desktop\\码农时光\\大三上课程\\课程做业\\"; 4 int num; 5 if(a == "张三1 123" || a == "张三2 123" || a == "张三3 123") 6 { 7 name_1 += a; 8 name_1 += "\\"; 9 cout<<"当前选择为小学出题"<<endl; 10 cout<<"准备生成小学数学题目,请输入生成题目数量:" ; 11 cin>>num; 12 if(num >= 10 || num <= 30) 13 { 14 mathsub_1(num); 15 } 16 } 17 18 else if(a == "李四1 123" || a == "李四2 123" || a == "李四3 123") 19 { 20 name_1 += a; 21 name_1 += "\\"; 22 cout<<"当前选择为初中出题"; 23 cout<<"准备生成初中数学题目,请输入生成题目数量:" ; 24 cin>>num; 25 if(num >= 10 || num <= 30) 26 { 27 mathsub_2(num); 28 } 29 } 30 31 else if(a == "王五1 123" || a == "王五2 123" || a == "王五3 123") 32 { 33 name_1 += a; 34 name_1 += "\\"; 35 cout<<"当前选择为高中出题"; 36 cout<<"准备生成高中数学题目,请输入生成题目数量:" ; 37 cin>>num; 38 if(num >= 10 || num <= 30) 39 { 40 mathsub_3(num); 41 } 42 } 43 44 else 45 { 46 cout<<"请输入正确的用户名、密码"<<endl; 47 string na; 48 getline(cin,na); 49 entry(na); 50 } 51 }
能够看到这里他选择将用户的帐户与密码这两个登陆信息做为一个字符串进行传参,以此来判断帐户类型,这是一种大胆的尝试。这里他成功采集了帐户的信息,而且将其做为路径中的一部分进行了插入,是必定的成功尝试。这里是用if()进行的判断,比起死循环判断法更容易退出循环。函数
2.2 Name()spa
1 int Name() //获取文件名称 2 { 3 time_t nowtime = time(NULL); 4 struct tm *p; 5 p = gmtime(&nowtime); 6 name = name_1; 7 8 char timeinfo[256] = {0}; 9 sprintf(timeinfo,"%d-%d-%d-%d-%d-%d.txt",1900+p->tm_year,1+p->tm_mon,p->tm_mday,8+p->tm_hour,p->tm_min,p->tm_sec); 10 name += timeinfo; 11 }
这里个人队友运用了time类中的内部结构体,struct tm,调用gmtime()函数进行了国际标准时间转化,最后使用sprintf()函数控制了格式化输出字符串,这里很是好,能够不用进行大规模字符串拼接,保证了函数的可读性。指针
2.3 mathsub_3()code
1 int mathsub_3(int n) //高中数学 2 { 3 srand(time(NULL)); 4 5 char fuhao_1[4] = {'+','-','*','/'}; 6 int x,y,z; 7 8 Name(); //获取当前时间即对应名字 9 char *p = (char*)name.data(); 10 ofstream fout; 11 fout.open(p); //打开txt文件 12 13 for(int i = 0;i<n;i++) 14 { 15 fout<<i+1<<". "; 16 17 x = rand()%5+1; //1-5个操做数 18 19 for(int j = 0;j<x;j++) 20 { 21 int qaq = rand()%4; 22 if(i == n-1&&qaq == 0) //确保至少有一个三角函数 23 { 24 qaq = rand()%3 + 1; 25 } 26 27 y = rand()%100+1; //1-100的取值 28 if(qaq == 1) 29 { 30 fout<<"sin("<<y<<")"; 31 } 32 else if(qaq == 2) 33 { 34 fout<<"cos("<<y<<")"; 35 } 36 else if(qaq == 3) 37 { 38 fout<<"tan("<<y<<")"; 39 } 40 else 41 { 42 fout<<y; 43 } 44 45 if(j != x-1) 46 { 47 z = rand()%4; //随机产生符号 48 fout<<fuhao_1[z]; 49 } 50 else 51 { 52 fout<<"="; 53 } 54 } 55 56 if(i != n-1) //未结束前换行 57 { 58 fout<<endl; 59 fout<<endl; 60 } 61 } 62 fout.close(); 63 }
这里我用我队友的高中代码来进行分析,个人队友利用字符指针的方式声明了一个字符数组,用来储存长度可变的字符串,这是一种C语言式的字符转换操做,说明其基本功较为扎实,另外两个阶段的函数与该函数相近似,说明其深谙函数操做,对高内聚低耦合有初步了解。这里他利用fstream对象进行文件的写出写入操做,并用qaq标志位判断当前须要插入的符号。队友巧妙的利用三角函数与括号须要同时出现这一点,直接进行了组合,而且在最后补足全部符号,不须要考虑双操做数这一特色,是一种较好的实现方式。对象
2.4 main()blog
1 int main() 2 { 3 string user,b; 4 getline(cin,user); //读取用户名和密码 5 entry(user); //进入帐号及获取试卷 6 7 while(cin>>b) //切换题目类型 8 { 9 int num; 10 if(b == "切换为小学") 11 { 12 cout<<"准备生成小学数学题目,请输入生成题目数量:" ; 13 cin>>num; 14 if(num >= 10 || num <= 30) 15 { 16 mathsub_1(num); 17 } 18 break; 19 } 20 if(b == "切换为初中") 21 { 22 cout<<"准备生成初中数学题目,请输入生成题目数量:" ; 23 cin>>num; 24 if(num >= 10 || num <= 30) 25 { 26 mathsub_2(num); 27 } 28 break; 29 } 30 else if(b == "切换为高中") 31 { 32 cout<<"准备生成高中数学题目,请输入生成题目数量:" ; 33 cin>>num; 34 if(num >= 10 || num <= 30) 35 { 36 mathsub_3(num); 37 } 38 break; 39 } 40 else 41 { 42 cout<<"请输入小学、初中和高中三个选项中的一个"; 43 } 44 } 45 46 return 0; 47 }
主函数中较好的组合了三种不一样的切换方式,同时也加入了输入判断,避免了死循环的判断方式,能够看到对输入有较好的处理,全部代码到此结束。ci
看完队友可圈可点的代码,咱们来略微分析队友代码中的缺点。
1. 安全性
队友代码中直接将帐户与密码明文传输,没有任何防御措施,这在开发中是很不安全的,遭受攻击后容易被直接拖库。另外这里的判断直接将用户帐户密码写在源代码里面进行判断,这里能够直接获取用户的帐户数据,能够考虑在数据库层面进行改进。
2. 可读性
队友代码中大规模出现,x,y,z等变量名,对阅读代码十分不友好,能够考虑注意代码的命名规范问题,提高代码的可读性。
3. 需求分析
队友在对需求文档的理解当中出现了一点的误差,没有实现查重功能,但基本功能已经实现,稍加完善便可避免。
整体来讲,队友的代码仍是很好的,其中对于输入检测方面有着独到的看法,这让我受益不浅,但愿在接下来的团队项目中能够与队友通力合做,完成项目。
感谢雷荣锋同窗提供代码!(请跟我念,雷荣锋牛逼!)