個人隊友和我同樣選取了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. 需求分析
隊友在對需求文檔的理解當中出現了一點的誤差,沒有實現查重功能,但基本功能已經實現,稍加完善便可避免。
整體來講,隊友的代碼仍是很好的,其中對於輸入檢測方面有着獨到的看法,這讓我受益不淺,但願在接下來的團隊項目中能夠與隊友通力合做,完成項目。
感謝雷榮鋒同窗提供代碼!(請跟我念,雷榮鋒牛逼!)