版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、<p><b> 目 錄</b></p><p><b> 1 需求分析1</b></p><p> 1.1問題描述1</p><p> 1.2輸入數(shù)據(jù)要求1</p><p> 1.3輸出數(shù)據(jù)要求2</p><p> 1.4開發(fā)環(huán)境和工具
2、4</p><p> 1.5成員分工4</p><p><b> 2 總體設(shè)計(jì)5</b></p><p> 2.1總體設(shè)計(jì)思路5</p><p> 2.2模塊結(jié)構(gòu)圖5</p><p><b> 2.3模塊說明6</b></p><p
3、> 3 詳細(xì)設(shè)計(jì)…………………………………………………………………………………………9</p><p> 3.1數(shù)據(jù)類型定義9</p><p> 1. 結(jié)構(gòu)體類型的定義及初始化9</p><p><b> 2定義全局變量9</b></p><p> 3.2 模塊實(shí)現(xiàn)9</p><
4、;p> MathPath模塊實(shí)現(xiàn)9</p><p> memo_read模塊實(shí)現(xiàn)10</p><p> memo_written模塊實(shí)現(xiàn)11</p><p> memo_modify模塊實(shí)現(xiàn)12</p><p> memo_delete模塊實(shí)現(xiàn)13</p><p> memo_delete_
5、all模塊實(shí)現(xiàn)14</p><p> 4 測試結(jié)果與分析………………………………………………………………………………..15</p><p><b> 5 總結(jié)20</b></p><p> 附錄………………………………………………………………………………………………..21</p><p><b>
6、 1 需求分析</b></p><p><b> 問題描述</b></p><p> 我們將該課題分解為萬年歷和備忘錄兩部分,兩人各完成其中的一部分。我們定義了一個(gè)struct date_message型結(jié)構(gòu)體變量date用來存放年月日以及對應(yīng)的備忘。</p><p> 由于課題要求使用命令行參數(shù)來實(shí)現(xiàn)各種功能,因此我們參考
7、了一系列C語言教材,自學(xué)了命令行參數(shù)的使用,并使用getopt函數(shù)來實(shí)現(xiàn)參數(shù)的分析,最后根據(jù)getopt函數(shù)返回的值用switch語句選擇程序的功能。(允許在輸入?yún)?shù)時(shí)只有年份月份沒有日期)</p><p> 關(guān)于萬年歷,我們先計(jì)算當(dāng)月第一天是星期幾,再依次將接下來的日期排下來。針對當(dāng)月第一天星期的求解,我們以2011年1月1日為基點(diǎn)(星期六),計(jì)算所求日期與該日相差的天數(shù)取余(討論年份在2011兩邊的兩種情況
8、),之后通過一定的輸出手段將日歷輸出。</p><p> 關(guān)于備忘,我們除了實(shí)現(xiàn)要求中的顯示功能和添加功能外,增加了程序的三項(xiàng)功能:修改功能、刪除單日備忘功能、刪除所有備忘功能。提供多備忘的添加功能。通過文件的寫入與讀取(刪除功能使用了空結(jié)構(gòu)體變量覆蓋的辦法),實(shí)現(xiàn)以上的各項(xiàng)功能。</p><p><b> 輸入數(shù)據(jù)要求</b></p><p&
9、gt; 由于使用了命令行參數(shù),所以該程序的運(yùn)行必須在DOS環(huán)境下。在“命令行提示符”中按“可執(zhí)行文件的路徑 空格 負(fù)號 命令選項(xiàng) 空格 命令選項(xiàng)所帶的參數(shù)”的順序輸入。我們將該文件命名為calender.exe,參數(shù)為年月日(允許在輸入?yún)?shù)時(shí)只有年份月份沒有日期,使用選項(xiàng)-t時(shí)不允許輸入年月日)。</p><p> 各命令選項(xiàng)的功能如下:</p><p> /*-d:顯示當(dāng)月日歷和當(dāng)
10、日備忘*/</p><p> /*-i:顯示當(dāng)月日歷和添加當(dāng)日備忘*/ </p><p> /*-m:顯示當(dāng)月日歷和修改當(dāng)日備忘*/ </p><p> /*-g:刪除當(dāng)日備忘*/</p><p> /*-t:刪除全部備忘*/</p><p> 下面就各命令選項(xiàng)給出一部分樣例:</p><
11、p> C:\Windows\system32>E:\calendar –d 2011 6 15</p><p> C:\Windows\system32>E:\calendar –i 6888 6 8</p><p> C:\Windows\system32>E:\calendar –m 9999 9 9</p><p> C:\Wi
12、ndows\system32>E:\calendar –g 12345 6 7</p><p> C:\Windows\system32>E:\calendar –t</p><p> 樣例輸入的截圖如下:</p><p><b> 輸出數(shù)據(jù)要求</b></p><p> 根據(jù)輸入?yún)?shù)信息,使用不同的
13、功能。注:允許多備忘存在,但此處不作為樣例截圖。</p><p> 針對樣例輸入的五種功能的輸出如下:</p><p> 顯示當(dāng)月日歷和當(dāng)日備忘:基本功能,顯示當(dāng)月日歷和當(dāng)日備忘。</p><p> 顯示當(dāng)月日歷和添加當(dāng)日備忘:輸入所需要添加的備忘,提示“添加成功后”之后顯示添加后的當(dāng)月日歷和當(dāng)日備忘。</p><p> 顯示當(dāng)月日歷
14、和修改當(dāng)日備忘:與添加備忘的程序運(yùn)行結(jié)果類似。</p><p> 刪除當(dāng)日備忘。提示確認(rèn)信息,當(dāng)輸入y時(shí)刪除。如果該日本身無備忘的話,提示“該日無備忘!”</p><p> 刪除全部備忘。提示確認(rèn)信息,當(dāng)輸入y時(shí)刪除。</p><p><b> 開發(fā)環(huán)境和工具</b></p><p> 開發(fā)環(huán)境:Windows
15、7</p><p> 開發(fā)工具:Dev-C++ 4.9.9.2</p><p><b> 成員分工</b></p><p> 胡凡:總體設(shè)計(jì)、主調(diào)模塊、備忘錄功能實(shí)現(xiàn)、注釋編寫</p><p> 葉磊:主調(diào)模塊、萬年歷功能實(shí)現(xiàn)、數(shù)據(jù)測試、注釋編寫</p><p><b> 2
16、總體設(shè)計(jì)</b></p><p><b> 2.1總體設(shè)計(jì)思路</b></p><p><b> 設(shè)計(jì)思路</b></p><p> 考慮到日期與備忘的一一對應(yīng),采用結(jié)構(gòu)體來解決該題成為一個(gè)可行的思路。首先,定義結(jié)構(gòu)體類型,使得年月日與備忘直接綁定在一起。通過程序中這一臨時(shí)存放數(shù)據(jù)的變量,使用文件的讀寫功
17、能向文件中寫入文件以及讀出信息以暫時(shí)使用。</p><p> 針對日歷的輸出,首要考慮的是當(dāng)月1日的輸出位置,即需要求出該月1日是星期幾。針對這個(gè)問題,我們以2011年1月1日為基點(diǎn),求所求日期與基點(diǎn)距離的天數(shù)之差,之后根據(jù)除以7取的余數(shù)來看星期。選擇2011年1月1日為基點(diǎn),是因?yàn)槠錆M足計(jì)算的兩個(gè)條件:1.該日正好為年首,使得計(jì)算相差天數(shù)的計(jì)算變得更為簡單。2.該日正好是星期六,使得相差的天數(shù)除以7所取出來的
18、余數(shù)正好按日歷從左至右顯示(我們輸出的日歷從左往右依次為星期日、一、二、三、四、五、六)。我們考慮2011年前與后的兩種情況。2011年后所需的即為正常余數(shù),2011年前的則需要用7減去得到的余數(shù)才是所欲要的值。之后經(jīng)過一定的輸出格式即可將日歷輸出。</p><p> 針對備忘錄的編寫,考慮到定義了一個(gè)結(jié)構(gòu)體使得年月日與備忘相連,因此可以將年月日與備忘一同存入文件??紤]到萬年備忘錄的龐大,為了節(jié)省時(shí)間和空間,我
19、們想出了一個(gè)算法:在添加寫入文件時(shí),一律將數(shù)據(jù)內(nèi)容寫入文件末尾(即使用ab+追加模式);而當(dāng)讀取文件時(shí),則將文件內(nèi)的年月日與外部參數(shù)輸入的年月日相比較,不相同則位置指針下移,一直到年月日相同或者無法讀取為止。這樣編寫可以避免考慮年份的上限大?。ㄒ?yàn)槿绻x一個(gè)二維數(shù)組,雖然也可以將日期和備忘一一對應(yīng),但是這樣的話處理這個(gè)數(shù)組的上限就不好操作了。如果數(shù)組開太大會直接影響運(yùn)行速度),而且在存入的備忘不太多的情況下在時(shí)間和空間上都可以節(jié)?。?/p>
20、間只跟存入的備忘數(shù)目有關(guān),而不是直接開很大的數(shù)組,這樣即使年份很大也不會對空間大小有什么影響)。另外,我們設(shè)計(jì)了備忘修改功能、備忘刪除(單日或全部),使得操作可以更人性化。另外,多備忘錄的添加、修改、刪除(當(dāng)天單條、當(dāng)天所有、全部天的備忘)都是允許的。</p><p> 最后,在自學(xué)了命令行參數(shù)之后,我們用argc和*argv[]將主函數(shù)寫出,并且用getopt函數(shù)來處理接收的參數(shù)并返回命令選項(xiàng)。之后便可以通過
21、返回的命令選項(xiàng)用switch語句選擇所需要實(shí)現(xiàn)的功能。</p><p> 以上即為我們對該課題的總體設(shè)計(jì)思路。</p><p><b> 數(shù)據(jù)存儲</b></p><p> 將年月日與對應(yīng)的備忘放于同一結(jié)構(gòu)體變量中,在使用文件讀寫時(shí)作為一個(gè)整體使用,也方便了添加功能、修改功能、刪除功能的實(shí)現(xiàn)。</p><p>&l
22、t;b> 2.2模塊結(jié)構(gòu)圖</b></p><p> 根據(jù)需求將系統(tǒng)劃分為四個(gè)功能模塊,函數(shù)之間的調(diào)用關(guān)系如圖2.1所示。</p><p> 圖2.1 晚年備忘錄的模塊結(jié)構(gòu)圖</p><p> 1)Main:主函數(shù)。</p><p> 2)leap:閏年判斷。</p><p> 3)che
23、ckDate:檢查日期合法性</p><p> 4)show_calender:顯示當(dāng)日的日歷(未輸入日時(shí)顯示當(dāng)月1日的日歷)。</p><p> 5)memo_read:備忘的讀取。</p><p> 6)memo_written:備忘的寫入。</p><p> 7)memo_modify:備忘的修改。</p><
24、;p> 8)memo_delete:備忘的刪除(當(dāng)日(其中分為單條刪除和全部刪除))。</p><p> 9)memo_delete_all:備忘的刪除(全部)。</p><p><b> 2.3模塊說明</b></p><p> ?。ㄒ詮纳现料拢瑥淖笾劣业捻樞蛘f明)</p><p> MathPath模塊
25、</p><p> 函數(shù)原型:int main(int argc,char *argv[])</p><p> 功 能:主函數(shù)</p><p> 輸入?yún)?shù):argc——int類型,表示錄入?yún)?shù)的個(gè)數(shù)</p><p> *argv[]——char類型,各元素記錄各種錄入字符串的首地址</p><p> 輸
26、出參數(shù):0——int類型,返回給系統(tǒng)一個(gè)值,說明程序正常終止</p><p><b> leap模塊</b></p><p> 函數(shù)原型:int leap(int t_year)</p><p> 功 能:閏年判斷</p><p> 輸入?yún)?shù):t_year——int類型,表示需要判斷閏年的年份</p&
27、gt;<p> 輸出參數(shù):1——int類型,如果是閏年則返回1;</p><p> 0——int類型,如果是非閏年則返回0;</p><p> 3. checkDate模塊</p><p> 函數(shù)原型:void checkDate()</p><p> 功 能:檢查輸入年月日的合法性</p><
28、;p> 輸入?yún)?shù):year——int類型,表示年份</p><p> month——int類型,表示月份</p><p> day——int類型,表示日期</p><p><b> 輸出參數(shù):無</b></p><p> 4. show_calender模塊</p><p> 函
29、數(shù)原型:void show_calender()</p><p> 功 能:顯示日歷</p><p> 輸入?yún)?shù):date.year——int類型,表示年份</p><p> date.month——int類型,表示月份</p><p> date.day——int類型,表示日期</p><p><
30、b> 輸出參數(shù):無</b></p><p> 5. memo_read模塊</p><p> 函數(shù)原型:void memo_read()</p><p> 功 能:從文件讀取備忘</p><p> 輸入?yún)?shù):date.year——int類型,表示年份</p><p> date.mo
31、nth——int類型,表示月份</p><p> date.day——int類型,表示日期</p><p><b> 輸出參數(shù):無</b></p><p> 6. memo_written模塊</p><p> 函數(shù)原型:void memo_written ()</p><p> 功
32、 能:將備忘寫入文件</p><p> 輸入?yún)?shù):date.year——int類型,表示年份</p><p> date.month——int類型,表示月份</p><p> date.day——int類型,表示日期</p><p><b> 輸出參數(shù):無</b></p><p> 7
33、. memo_modify模塊</p><p> 函數(shù)原型:void memo_modify ()</p><p> 功 能:修改備忘</p><p> 輸入?yún)?shù):date.year——int類型,表示年份</p><p> date.month——int類型,表示月份</p><p> date.da
34、y——int類型,表示日期</p><p><b> 輸出參數(shù):無</b></p><p> 8. memo_delete模塊</p><p> 函數(shù)原型:void memo_delete ()</p><p> 功 能:刪除備忘(當(dāng)日)</p><p> 輸入?yún)?shù):date.ye
35、ar——int類型,表示年份</p><p> date.month——int類型,表示月份</p><p> date.day——int類型,表示日期</p><p><b> 輸出參數(shù):無</b></p><p> 9. memo_delete_all模塊</p><p> 函數(shù)原型
36、:void memo_delete_all ()</p><p> 功 能:刪除備忘(全部)</p><p><b> 輸入?yún)?shù):無</b></p><p><b> 輸出參數(shù):無</b></p><p><b> 3 詳細(xì)設(shè)計(jì)</b></p>&l
37、t;p><b> 3.1數(shù)據(jù)類型定義</b></p><p> 1. 結(jié)構(gòu)體類型的定義及初始化</p><p> /*定義結(jié)構(gòu)體*/ </p><p> struct date_message</p><p><b> {</b></p><p> int
38、year; /*年*/ </p><p> int month; /*月*/ </p><p> int day; /*日*/ </p><p> char memo[300]; /*備忘*/ </p><p> }date={1,1,1,"\0&q
39、uot;};</p><p><b> 2定義全局變量</b></p><p> /*定義全局變量(各月所含天數(shù))*/ </p><p> int a[]={0,31,0,31,30,31,30,31,31,30,31,30,31};</p><p><b> 3.2 模塊實(shí)現(xiàn)</b><
40、;/p><p> 由于各人分工,故以下貼出的是自己負(fù)責(zé)模塊的實(shí)現(xiàn)(此部分為備忘錄功能模塊的實(shí)現(xiàn))</p><p> MathPath模塊實(shí)現(xiàn)</p><p><b> 算法思想</b></p><p> 首先進(jìn)行函數(shù)調(diào)用聲明。定義一個(gè)變量choice,用來記錄getopt函數(shù)分析完參數(shù)之后的返回值,即命令選項(xiàng),之后使
41、用switch語句對命令選項(xiàng)進(jìn)行判斷,根據(jù)不同的命令選項(xiàng)執(zhí)行不同的功能。</p><p><b> 具體實(shí)現(xiàn)</b></p><p><b> ?。P(guān)鍵代碼)</b></p><p> int main(int argc,char *argv[]) </p><p><b> {
42、</b></p><p><b> /*函數(shù)聲明*/ </b></p><p> void checkDate(); /*檢查日期合法性*/</p><p> void show_calender(); /*顯示日歷*/</p><p> v
43、oid memo_written(); /*寫入備忘*/</p><p> void memo_modify(); /*修改備忘*/ </p><p> void memo_delete(); /*刪除當(dāng)日備忘*/</p><p> void memo_delete_all
44、(); /*刪除全部備忘*/</p><p> void memo_read(); /*讀取備忘*/</p><p><b> /*定義變量*/ </b></p><p> int choice;</p><p> /*使用getopt函數(shù)分析命令行參數(shù),識
45、別選項(xiàng)*/</p><p> while((choice=getopt(argc,argv,"d:i:m:g:t"))!=-1) </p><p> { /*選項(xiàng)*/ </p><p> switch(choice) </p><p>
46、 { case 'd':/*調(diào)用函數(shù),顯示當(dāng)月日歷和當(dāng)日備忘*/</p><p> case 'i': /*調(diào)用函數(shù),顯示當(dāng)月日歷和添加當(dāng)日備忘*/</p><p> case 'm': /*調(diào)用函數(shù),顯示當(dāng)月日歷和修改當(dāng)日備忘*/</p><p> case 'g':
47、/*調(diào)用函數(shù),刪除當(dāng)日備忘*/</p><p> case 't': /*調(diào)用函數(shù),刪除全部備忘*/</p><p><b> }</b></p><p><b> }</b></p><p> printf("\t\t Please any key to
48、continue…………"); </p><p> getchar();</p><p> system("cls");</p><p><b> return 0;</b></p><p><b> }</b></p><p> me
49、mo_read模塊實(shí)現(xiàn)</p><p><b> 1算法思想</b></p><p> 依次讀取文件的一個(gè)結(jié)構(gòu)體長度的數(shù)據(jù),直到讀取的年月日與外部輸入的年月日相等或者文件無法繼續(xù)讀取,再將最后讀取的年月日輸出。</p><p><b> 2具體實(shí)現(xiàn)</b></p><p><b>
50、?。P(guān)鍵代碼)</b></p><p><b> /*備忘讀取*/</b></p><p> void memo_read()</p><p><b> {</b></p><p> /*定義文件指針*/</p><p><b> FILE *
51、fp;</b></p><p><b> /*定義變量*/</b></p><p><b> int i;</b></p><p> struct date_message temp={0,0,0,"\0"};</p><p> /*總是在讀取備忘之前令備忘數(shù)
52、歸零*/</p><p> count_memo=0;</p><p><b> /*打開文件*/</b></p><p> if((fp=fopen("calender.txt","ab+"))==NULL)</p><p><b> {</b>&l
53、t;/p><p> printf("\t\t\t\t打開文件失敗\t\t\t\t\n");</p><p><b> return;</b></p><p><b> }</b></p><p> /*查找文件中是否有相同的日期*/ </p><p>
54、<b> while(1) </b></p><p><b> { </b></p><p> /*文件讀到不能讀取為止*/ </p><p> if(fread(&temp,sizeof(struct date_message),1,fp)!=1)break;</p><p>
55、; /*如果文件該位置的時(shí)間與所求時(shí)間相同*/</p><p> if((temp.year==date.year)&&(temp.month==date.month)&&(temp.day==date.day))</p><p><b> {</b></p><p> /*當(dāng)天備忘個(gè)數(shù)的計(jì)數(shù)*/<
56、/p><p> count_memo++;</p><p> for(i=0;i<300;i++) </p><p> date.memo[i]=temp.memo[i];</p><p> printf("\n\t\t\t備忘%d:%s\n",count_memo,date.memo); </p>
57、<p><b> } </b></p><p><b> }</b></p><p> /*如果沒有相同日期的話*/ </p><p> if(count_memo==0)</p><p> printf("\t\t\t\t該日暫無備忘\n\n");&l
58、t;/p><p> printf("\n");</p><p> fclose(fp);</p><p><b> }</b></p><p> memo_written模塊實(shí)現(xiàn)</p><p><b> 1算法思想</b></p>&
59、lt;p> 使用文件的追加模式打開,每次將需要寫入的數(shù)據(jù)寫于文件最后。</p><p><b> 2具體實(shí)現(xiàn)</b></p><p><b> ?。P(guān)鍵代碼)</b></p><p><b> /*備忘寫入*/</b></p><p> void memo_wri
60、tten()</p><p><b> {</b></p><p> /*定義文件指針*/</p><p><b> FILE *fp;</b></p><p><b> /*打開文件*/</b></p><p> if((fp=fopen(&
61、quot;calender","ab+"))==NULL)</p><p><b> {</b></p><p> printf("\n\t\t\t\t 打開文件失敗\n\n\t\t\t ");</p><p><b> return;</b></p&g
62、t;<p><b> }</b></p><p><b> /*輸入備忘*/</b></p><p> scanf("%s",date.memo);</p><p><b> /*寫入備忘*/</b></p><p> if(fwri
63、te(&date,sizeof(struct date_message),1,fp)==1)</p><p><b> {</b></p><p> system("cls"); </p><p> printf("\n\t\t\t\t 備忘存入成功\n\n\t\t\t ");<
64、;/p><p><b> }</b></p><p><b> else </b></p><p><b> {</b></p><p> system("cls"); </p><p> printf("\n\t\t
65、\t\t 備忘存入失敗\n\n\t\t\t ");</p><p><b> }</b></p><p> getchar();</p><p> fclose(fp);</p><p><b> }</b></p><p> memo_modif
66、y模塊實(shí)現(xiàn)</p><p><b> 1算法思想</b></p><p> 依次讀取文件的一個(gè)結(jié)構(gòu)體長度的數(shù)據(jù),直到讀取的年月日與外部輸入的年月日相等或者文件無法繼續(xù)讀取,調(diào)整位置指針的位置使得指針指向需要修改的結(jié)構(gòu)體,之后將需要修改的數(shù)據(jù)寫入即可。</p><p><b> 2具體實(shí)現(xiàn)</b></p>
67、<p><b> (關(guān)鍵代碼)</b></p><p><b> /*備忘修改*/</b></p><p> void memo_modify()</p><p><b> {</b></p><p> /*定義文件指針*/</p><
68、p><b> FILE *fp;</b></p><p><b> /*定義變量*/</b></p><p> int i=0,t,count=0;</p><p> struct date_message temp;</p><p><b> /*打開文件*/</b
69、></p><p> if((fp=fopen("calender.txt","rb+"))==NULL)</p><p><b> {</b></p><p> printf("\n\n\n\n\n\n\n\n\n\t\t\t 打開文件失敗\n\n");</
70、p><p><b> return;</b></p><p><b> }</b></p><p> printf("請輸入要修改第幾條備忘\n"); </p><p> /*輸入需要修改第幾條備忘*/</p><p> scanf("%d
71、",&t);</p><p> if(!(t>0&&t<=count_memo))</p><p><b> {</b></p><p> printf("輸入錯誤!該次操作失敗\n!");</p><p><b> getch();&l
72、t;/b></p><p> system("cls");</p><p><b> exit(0);</b></p><p><b> }</b></p><p> printf("請輸入要修改的內(nèi)容\n"); </p><
73、p><b> /*輸入備忘*/</b></p><p> scanf("%s",&date.memo);</p><p> /*在文件中尋找該日期*/</p><p><b> while(1)</b></p><p><b> { <
74、;/b></p><p> /*移動指針位置*/</p><p> fseek(fp,i*sizeof(struct date_message),0);</p><p> /*到文件無法讀取時(shí)退出*/</p><p> if(fread(&temp,sizeof(struct date_message),1,fp)!=1
75、)break;</p><p> /*如果文件中的時(shí)間與所求時(shí)間相同*/</p><p> if((temp.year==date.year)&&(temp.month==date.month)&&(temp.day==date.day))</p><p><b> {</b></p><
76、;p> /*備忘計(jì)數(shù)+1*/</p><p><b> count++;</b></p><p> /*對應(yīng)上同一個(gè)備忘的時(shí)候*/</p><p> if(count==t)</p><p><b> { </b></p><p> fseek(fp,
77、i*sizeof(struct date_message),0);</p><p><b> /*覆蓋*/</b></p><p> fwrite(&date,sizeof(struct date_message),1,fp);</p><p><b> break;</b></p><p
78、><b> }</b></p><p><b> } </b></p><p><b> i++; </b></p><p><b> }</b></p><p> printf("\n\t\t\t\t 修改成功!\n\n&q
79、uot;);</p><p><b> getch();</b></p><p> system("cls");</p><p> fclose(fp);</p><p><b> }</b></p><p> memo_delete模塊實(shí)現(xiàn)&l
80、t;/p><p><b> 1算法思想</b></p><p> 依次讀取文件的一個(gè)結(jié)構(gòu)體長度的數(shù)據(jù),直到讀取的年月日與外部輸入的年月日相等或者文件無法繼續(xù)讀取,調(diào)整位置指針的位置使得指針指向需要刪除的結(jié)構(gòu)體,之后將空結(jié)構(gòu)體寫入即可。</p><p><b> 2具體實(shí)現(xiàn)</b></p><p>
81、<b> ?。P(guān)鍵代碼)</b></p><p> /*當(dāng)日備忘刪除*/</p><p> void memo_delete()</p><p><b> {</b></p><p> /*定義文件指針*/</p><p><b> FILE *fp;&l
82、t;/b></p><p><b> /*定義變量*/</b></p><p> int i=0,t,choice,count=0;</p><p> struct date_message temp1={0,0,0,"\0"};</p><p> struct date_message
83、 temp2;</p><p><b> /*確認(rèn)信息*/</b></p><p> printf("確認(rèn)要刪除當(dāng)日備忘嗎(y/n)? "); </p><p> /*如果輸入y的話刪除*/ </p><p> if(!(getchar()=='y'||'Y'
84、))</p><p><b> { </b></p><p> printf("未刪除該日任何備忘\n"); </p><p><b> getch();</b></p><p> system("cls");</p><p&g
85、t;<b> exit(0);</b></p><p><b> }</b></p><p> printf("(1)刪除單條備忘 or (2)刪除當(dāng)日所有備忘?\n請輸入1或2進(jìn)行選擇\n");</p><p> scanf("%d",&choice);</p
86、><p> switch(choice)</p><p><b> {</b></p><p> case 1:printf("請輸入要刪除第幾條備忘\n"); </p><p> /*輸入要刪除第幾條備忘*/</p><p> scanf("%d",
87、&t);</p><p> if(!(t>0&&t<=count_memo))</p><p><b> {</b></p><p> printf("輸入錯誤!該次操作失??!");</p><p><b> getch();</b>&
88、lt;/p><p> system("cls");</p><p><b> exit(0);</b></p><p><b> } </b></p><p><b> /*打開文件*/</b></p><p> if((
89、fp=fopen("calender.txt","rb+"))==NULL)</p><p><b> {</b></p><p> printf("打開文件失敗\n\n");</p><p><b> return;</b></p><
90、p><b> }</b></p><p> /*在文件中查找輸入的年月日的信息*/</p><p><b> while(1)</b></p><p><b> {</b></p><p> fseek(fp,i*sizeof(struct date_messa
91、ge),0);</p><p> if((fread(&temp2,sizeof(struct date_message),1,fp))!=1)break;</p><p> if((temp2.year==date.year)&&(temp2.month==date.month)&&(temp2.day==date.day))</p>
92、;<p><b> {</b></p><p><b> count++;</b></p><p> if(count==t)</p><p><b> { </b></p><p> fseek(fp,i*sizeof(struct date_m
93、essage),0);</p><p> /*將空的覆蓋上去*/</p><p> fwrite(&temp1,sizeof(struct date_message),1,fp);</p><p><b> break;</b></p><p><b> }</b></p>
94、;<p><b> }</b></p><p><b> i++; </b></p><p><b> }</b></p><p> printf("單條備忘刪除成功!\n");</p><p><b> getch()
95、; </b></p><p> system("cls");</p><p> fclose(fp);</p><p><b> break;</b></p><p> case 2:/*打開文件*/</p><p> if((fp=fopen("
96、;calender.txt","rb+"))==NULL)</p><p><b> {</b></p><p> printf("打開文件失敗\n\n");</p><p><b> return;</b></p><p><b>
97、 }</b></p><p> /*在文件中查找輸入的年月日的信息*/</p><p><b> while(1)</b></p><p><b> {</b></p><p> fseek(fp,i*sizeof(struct date_message),0);</p&
98、gt;<p> if(fread(&temp2,sizeof(struct date_message),1,fp)!=1)break;</p><p> if((temp2.year==date.year)&&(temp2.month==date.month)&&(temp2.day==date.day)) </p><p>&
99、lt;b> { </b></p><p> fseek(fp,i*sizeof(struct date_message),0);</p><p> fwrite(&temp1,sizeof(struct date_message),1,fp);</p><p><b> } </b></p>
100、;<p><b> i++;</b></p><p><b> }</b></p><p> printf("當(dāng)日所有備忘刪除成功!\n");</p><p><b> getch(); </b></p><p> system(&q
101、uot;cls");</p><p> fclose(fp);</p><p><b> break;</b></p><p> default:printf("輸入錯誤!操作失??!");</p><p><b> getch();</b></p>
102、<p> system("cls");</p><p><b> exit(0);</b></p><p><b> }</b></p><p><b> }</b></p><p> memo_delete_all模塊實(shí)現(xiàn)</p
103、><p><b> 1算法思想</b></p><p> 從文件開頭開始,每次將一個(gè)空結(jié)構(gòu)體覆蓋上已經(jīng)存在的結(jié)構(gòu)體,直到文件無法繼續(xù)讀取為止。</p><p><b> 2具體實(shí)現(xiàn)</b></p><p><b> (關(guān)鍵代碼)</b></p><p&g
104、t; /*全部備忘刪除*/</p><p> void memo_delete_all()</p><p><b> {</b></p><p> /*定義文件指針*/</p><p><b> FILE *fp;</b></p><p><b> /*
105、定義變量*/</b></p><p><b> int i=0;</b></p><p> struct date_message temp1={0,0,0,"\0"};</p><p> struct date_message temp2;</p><p><b> /
106、*打開文件*/</b></p><p> if((fp=fopen("calender","wb+"))==NULL)</p><p> { printf("打開文件失敗\n\n");</p><p><b> return;</b></p>&l
107、t;p><b> }</b></p><p> /*將位置指針依次后移,將所有的內(nèi)容覆蓋*/</p><p><b> do</b></p><p> { fseek(fp,i*sizeof(struct date_message),0);</p><p> if(fread(
108、&temp2,sizeof(struct date_message),1,fp)!=1)break;</p><p> fseek(fp,i*sizeof(struct date_message),0);</p><p> fwrite(&temp1,sizeof(struct date_message),1,fp);</p><p><b
109、> i++;</b></p><p> }while(1);</p><p> printf("全部刪除成功!\n\n");</p><p> fclose(fp);</p><p><b> } </b></p><p><b> 4
110、 測試結(jié)果及分析</b></p><p> 為了檢驗(yàn)該程序的可行性以及正確性,我們選擇了幾組有代表的測試數(shù)據(jù),與實(shí)際結(jié)果符合得很好。測試數(shù)據(jù)如下:</p><p> 選擇了2011年前的一天。我們選擇了1949年10月1日,預(yù)期結(jié)果為星期一,先查看其備忘,預(yù)期結(jié)果為“該日暫無備忘!”。之后添加備忘“中華人民共和國成立!”下面為測試時(shí)所截的圖。</p><
111、p> 在“命令提示行”中輸入?yún)?shù)</p><p><b> 敲回車,得到結(jié)果:</b></p><p> 該日添加備忘“中華人民共和國成立!”。下為參數(shù)輸入:</p><p> d.敲回車后提示輸入備忘。輸入備忘。</p><p><b> 按回車后</b></p>&
112、lt;p> 敲回車,得到成功信息,并輸出修改后的日歷及備忘。</p><p> 還需要測試年份大于2011年的日期??紤]到這份日歷為萬年歷,于是測試兩份數(shù)據(jù):大于一萬年和小于一萬年。以下測試小于一萬年的數(shù)據(jù):2012年12月24日,先添加備忘“世界末日?”再修改為“不可能是世界末日!”,最后刪除該日備忘。</p><p><b> 輸入?yún)?shù)(添加)</b>
113、</p><p><b> 添加備忘</b></p><p><b> 添加成功信息</b></p><p><b> 輸入?yún)?shù)(修改)</b></p><p><b> 輸入修改內(nèi)容</b></p><p><b&g
114、t; 修改成功</b></p><p><b> 輸入?yún)?shù)(刪除)</b></p><p><b> 確認(rèn)刪除后</b></p><p> 最后測試一組大于一萬年的日期:999999年9月9日.測試功能:添加功能、全部刪除功能。</p><p><b> 輸入?yún)?shù)&l
115、t;/b></p><p><b> 輸入備忘</b></p><p><b> 添加成功</b></p><p> 輸入?yún)?shù)(刪除全部)</p><p><b> 確認(rèn)刪除后</b></p><p> 至此,數(shù)據(jù)測試完畢。所有的測試結(jié)果
116、均與實(shí)際符合得很好,驗(yàn)證了該程序的正確性。</p><p><b> 5 總結(jié)</b></p><p><b> 1 算法與程序總結(jié)</b></p><p> 本程序定義了結(jié)構(gòu)體類型,將年月日和備忘聯(lián)系起來,在寫入和讀取的過程中均作為一個(gè)整體,并且在將寫入的內(nèi)容始終寫在文件的末尾,而不是定義一一對應(yīng)的備忘數(shù)組,節(jié)省了
117、時(shí)間和空間。</p><p> 對于多備忘的問題,我們構(gòu)思了一種算法,最終解決了多備忘的添加、修改、刪除功能。</p><p> 由于課題要求使用命令行參數(shù),所以,沒有使用菜單來實(shí)現(xiàn)功能,而是使用命令選項(xiàng)來選擇所需要執(zhí)行的功能。而由于使用了命令行參數(shù),因此該程序必須在DOS環(huán)境下運(yùn)行(命令提示行)。</p><p> 萬年歷部分,采用定基點(diǎn)求相差的天數(shù)取7的余
118、來確定當(dāng)月首日是星期幾,從而得到所需要的日歷。</p><p><b> 2 改進(jìn)方案</b></p><p> a.刪除功能使用的算法略有缺點(diǎn)。因?yàn)椴捎昧烁采w法來刪除,所以覆蓋后的文件中實(shí)際上仍然有一段空的內(nèi)容,雖然對程序沒有太大影響,但是當(dāng)刪除的備忘比較多時(shí)也會占用一定不必要的資源。實(shí)際上還有一種算法,將所有的內(nèi)容讀取出,然后刪去不需要的,再將剩余的寫入回去,
119、或許這樣的效果能更好一些。至于全部刪除,直接在命令行參數(shù)中使用rmdir命令會更快一些,但由于時(shí)間有限,沒有進(jìn)行嘗試。</p><p> b.萬年歷的算法有待簡化??梢圆捎貌汤展剑苯佑?jì)算出任何日期是星期幾,而且不需要設(shè)置基點(diǎn)。但蔡勒公式有使用限制,如果可以解決的話應(yīng)該可以簡化萬年歷的算法。</p><p> c.在了解更多的命令行參數(shù)之后,我們的程序可以更加專業(yè)化,也可以使得程序功
120、能更加強(qiáng)大。</p><p><b> 附錄</b></p><p> 以下為我們小組該課題的最終代碼:</p><p> /*-------------------------------我是分割線-------------------------------*/</p><p> /*命令行功能選項(xiàng)*/<
121、;/p><p> /*-d:顯示當(dāng)月日歷和當(dāng)日備忘*/</p><p> /*-i:顯示當(dāng)月日歷和添加當(dāng)日備忘*/ </p><p> /*-m:顯示當(dāng)月日歷和修改當(dāng)日備忘*/ </p><p> /*-g:刪除當(dāng)日備忘*/</p><p> /*-t:刪除全部備忘*/</p><p>
122、 /*-------------------------------我是分割線-------------------------------*/</p><p><b> /*頭文件*/ </b></p><p> #include<stdio.h></p><p> #include<stdlib.h></
123、p><p> #include<conio.h></p><p> #include<unistd.h> /*調(diào)用getopt函數(shù)*/</p><p> /*-------------------------------我是分割線-------------------------------*/</p><p>
124、; /*定義全局變量(各月所含天數(shù))*/ </p><p> int a[]={0,31,0,31,30,31,30,31,31,30,31,30,31};</p><p> /*定義全局變量(已獲取的備忘個(gè)數(shù))*/</p><p> int count_memo;</p><p> /*定義結(jié)構(gòu)體*/ </p>&l
125、t;p> struct date_message</p><p><b> {</b></p><p> int year; /*年*/ </p><p> int month; /*月*/ </p><p> int day; /*日*/
126、 </p><p> char memo[300]; /*備忘*/ </p><p> }date={1,1,1,"\0"};</p><p> /*-------------------------------我是分割線-------------------------------*/</p><p>&
127、lt;b> /*主函數(shù)*/ </b></p><p> int main(int argc,char *argv[]) </p><p><b> {</b></p><p><b> /*函數(shù)聲明*/ </b></p><p> void checkDate(
128、); /*檢查日期合法性*/</p><p> void show_calender(); /*顯示日歷*/</p><p> void memo_written(); /*寫入備忘*/</p><p> void memo_modify();
129、 /*修改備忘*/ </p><p> void memo_delete(); /*刪除當(dāng)日備忘*/</p><p> void memo_delete_all(); /*刪除全部備忘*/</p><p> void memo_read(); /*讀取備忘*/</p&g
130、t;<p><b> /*定義變量*/ </b></p><p> char choice;</p><p> /*使用getopt函數(shù)分析命令行參數(shù),識別選項(xiàng)*/</p><p> while((choice=getopt(argc,argv,"d:i:m:g:t"))!=-1) <
131、/p><p> { /*選項(xiàng)*/ </p><p> switch(choice) </p><p> { /*選項(xiàng)為d時(shí),顯示當(dāng)月日歷和當(dāng)日備忘*/</p><p> case 'd':/*調(diào)用atoi函數(shù),將字符型數(shù)字轉(zhuǎn)化為整
132、型*/ </p><p> date.year=atoi(argv[2]); </p><p> /*如果沒有輸入月份則不賦值*/ </p><p> if(atoi(argv[3])!=0)date.month=atoi(argv[3]);</p><p> /*如果沒有輸入日期則不賦值*/</p>&l
133、t;p> if(atoi(argv[4])!=0)date.day=atoi(argv[4]); </p><p> /*檢查日期合法性*/ </p><p> checkDate(); </p><p> /*顯示當(dāng)日日歷*/ </p><p> show_calender();
134、 </p><p> /*顯示備忘*/ </p><p> memo_read(); </p><p><b> break;</b></p><p> /*選項(xiàng)為i時(shí),顯示當(dāng)月日歷和添加當(dāng)日備忘*/</p><p> ca
135、se 'i':date.year=atoi(argv[2]);</p><p> date.month=atoi(argv[3]);</p><p> if(atoi(argv[4])!=0)date.day=atoi(argv[4]);</p><p> checkDate();</p><p> show_cale
136、nder();</p><p> memo_read();</p><p> printf("請輸入要添加的備忘\n"); </p><p><b> /*寫入備忘*/</b></p><p> memo_written(); </p><p> /*
137、添加之后*/ </p><p> printf("添加之后的日歷與對應(yīng)的備忘為\n"); </p><p> show_calender();</p><p> memo_read();</p><p><b> break;</b></p><p
138、> /*選項(xiàng)為m時(shí),顯示當(dāng)月日歷和修改當(dāng)日備忘*/ </p><p> case 'm':date.year=atoi(argv[2]);</p><p> date.month=atoi(argv[3]);</p><p> if(atoi(argv[4])!=0)date.day=atoi(argv[4]);<
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 萬年歷課程設(shè)計(jì)
- 萬年歷課程設(shè)計(jì)
- 萬年歷課程設(shè)計(jì)
- 萬年歷課程設(shè)計(jì)
- 萬年歷課程設(shè)計(jì)
- 萬年歷課程設(shè)計(jì)
- 萬年歷課程設(shè)計(jì)
- java萬年歷課程設(shè)計(jì)
- 萬年歷課程設(shè)計(jì)報(bào)告
- 數(shù)字萬年歷課程設(shè)計(jì)
- java課程設(shè)計(jì)--萬年歷
- 萬年歷課程設(shè)計(jì)論文
- 課程設(shè)計(jì)-萬年歷系統(tǒng)
- 萬年歷課程設(shè)計(jì)報(bào)告
- 數(shù)碼萬年歷課程設(shè)計(jì)
- 萬年歷課程設(shè)計(jì).doc
- java課程設(shè)計(jì)--萬年歷設(shè)計(jì)
- dsp課程設(shè)計(jì)-萬年歷設(shè)計(jì)
- 編寫萬年歷系統(tǒng)課程設(shè)計(jì)
- c++萬年歷課程設(shè)計(jì)
評論
0/150
提交評論