C語言源程序的自動評判畢業(yè)設(shè)計(jì)論文.doc_第1頁
C語言源程序的自動評判畢業(yè)設(shè)計(jì)論文.doc_第2頁
C語言源程序的自動評判畢業(yè)設(shè)計(jì)論文.doc_第3頁
C語言源程序的自動評判畢業(yè)設(shè)計(jì)論文.doc_第4頁
C語言源程序的自動評判畢業(yè)設(shè)計(jì)論文.doc_第5頁
已閱讀5頁,還剩63頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

蘇州科技學(xué)院畢業(yè)論文目 錄第1章 引言111 背景介紹11.1.1 研究背景簡介11.1.2 C語言簡介1第2章 概要設(shè)計(jì)321 方案設(shè)計(jì)32.1.1 開發(fā)環(huán)境32.1.2 工作方式32.1.3 系統(tǒng)目標(biāo)322 系統(tǒng)功能323 需要解決問題424 系統(tǒng)流程42.4.1 基本流程42.4.2 具體實(shí)現(xiàn)5第3章 詳細(xì)設(shè)計(jì)731 系統(tǒng)模塊化分73.1.1 添加文件對話框73.1.2 編譯鏈接函數(shù)83.1.3 運(yùn)行/評判對話框932 系統(tǒng)模塊具體實(shí)現(xiàn)103.2.1 準(zhǔn)備工作103.2.2 實(shí)現(xiàn)添加文件對話框113.2.3 實(shí)現(xiàn)編譯鏈接函數(shù)153.2.4 實(shí)現(xiàn)運(yùn)行/評判對話框19第4章 測試2641 測試方案2642 運(yùn)行界面264.2.1 準(zhǔn)備系統(tǒng)運(yùn)行264.2.2 系統(tǒng)測試27結(jié)論30致謝32參考文獻(xiàn)33附錄A 外文參考文獻(xiàn)(譯文)34附錄B 外文參考文獻(xiàn)(原文)4867第1章 引言11 背景介紹1.1.1 研究背景簡介C語言是目前國際上廣泛流行的、重要的計(jì)算機(jī)高級語言之一。它適合作為系統(tǒng)描述語言,即可用來編寫系統(tǒng)軟件,也可用來編寫應(yīng)用軟件。對于學(xué)習(xí)計(jì)算機(jī)專業(yè)的學(xué)生來說,學(xué)好C語言將為今后學(xué)習(xí)其他編程語言打下良好的基礎(chǔ),而隨著計(jì)算機(jī)應(yīng)用的普及,更多的其他非計(jì)算機(jī)專業(yè)也會需要學(xué)習(xí)編寫簡單的程序,C語言也是一個很不錯的選擇。學(xué)習(xí)C語言,首先是要學(xué)習(xí)理論知識,閱讀編程思想,閱讀源代碼,其次就是動手實(shí)踐上機(jī)編寫程序了。只有通過自己編寫程序,才能更好的掌握理論知識,發(fā)現(xiàn)不足,取得進(jìn)步。傳統(tǒng)的教學(xué)方式中,學(xué)生采用FTP,Email甚至手寫的方式提交編程作業(yè),老師一般采用逐一檢查并試運(yùn)行的手工檢查方式,然后給出相應(yīng)的得分。由于在編程作業(yè)的提交過程中,很多學(xué)生可能會把一些有語法錯誤以及結(jié)果不正確的程序提交上來,這就需要花費(fèi)老師很多的精力和時間,效果也不是很好。當(dāng)前,采用計(jì)算機(jī)對源程序直接進(jìn)行評判還不是很普遍。因此,有必要開發(fā)一套簡單易用的C語言源程序的自動評判系統(tǒng),幫助老師檢查學(xué)生的編程作業(yè),提高老師工作效率,減輕老師負(fù)擔(dān)。1.1.2 C語言簡介C語言是國際上廣泛流行的、很有發(fā)展前途的計(jì)算機(jī)高級語言。它適合作為系統(tǒng)描述語言,即可用來編寫系統(tǒng)軟件,也可用來編寫應(yīng)用軟件。 早期的操作系統(tǒng)等系統(tǒng)軟件主要是用匯編語言編寫的(包括 UNIX操作系統(tǒng)在內(nèi))。由于匯編語言依賴于計(jì)算機(jī)硬件,程序的可讀性和可移植性都比較差。為了提高可讀性和可移植性,最好改用高級語言,但一般的高級語言難以實(shí)現(xiàn)匯編語言的某些功能(匯編語言可以直接對硬件進(jìn)行操作),例如:對內(nèi)存地址的操作、位操作等)。人們設(shè)想能否找到一種既具有一般高級語言特性,又具有低級語言特性的語言,集它們的優(yōu)點(diǎn)于一身。于是,C語言就在這種情況下應(yīng)運(yùn)而生了。 C語言是在B語言的基礎(chǔ)上發(fā)展起來的,它的根源可以追溯到ALGOL 60。 1960年出現(xiàn)的ALGOL 60是一種面向問題的高級語言,它離硬件比較遠(yuǎn),不宜用來編寫系統(tǒng)程序。1963年英國的劍橋大學(xué)推出了CPL語言。1967年英國劍橋大學(xué)的Matin Richards對 CPL語言作了簡化,推出了BCPL語言。1970年美國貝爾實(shí)驗(yàn)室的 Ken Thompson以 BCPL語言為基礎(chǔ),又作了進(jìn)一步簡化,設(shè)計(jì)出了很簡單的而且很接近硬件的 B語言,并用 B語言寫第一個UNIX操作系統(tǒng),在PDP-7上實(shí)現(xiàn)。 1971年在PDP-11/20上實(shí)現(xiàn)了B語言,并寫了UNIX操作系統(tǒng)。但B語言過于簡單,功能有限。1972年至 1973年間,貝爾實(shí)驗(yàn)室的 D.M.Ritchie在B語言的基礎(chǔ)上設(shè)計(jì)出了C語言(取 BCPL的第二個字母)。最初的C語言只是為描述和實(shí)現(xiàn)UNIX操作系統(tǒng)提供一種工作語言而設(shè)計(jì)的。1973年,K.Thom- pson和D.M.ritchie兩人合作把UNIX的90%以上用 C改寫。 后來,C語言多次作了改進(jìn),但主要還是在貝爾實(shí)驗(yàn)室內(nèi)部使用。直到1- 975年UNIX第6版公布后 ,C語言的突出優(yōu)點(diǎn)才引起人們普遍注意。1977年出現(xiàn)了不依賴于具體機(jī)器的C語言編譯文本可移植C語言編譯程序,使C移植到其它機(jī)器時所做的工作大大簡化了,這也推動了UNIX操作系統(tǒng)迅速地在各種機(jī)器上實(shí)現(xiàn)。隨著 UNIX的日益廣泛使用,C語言也迅速得到推廣。C語言和UNIX可以說是一對孿生兄弟,在發(fā)展過程中相輔相成。1978年以后,C語言已先后移植到大、中、小、微型機(jī)上,已獨(dú)立于UNIX和PDP了。現(xiàn)在C語言已風(fēng)靡全世界,成為世界上應(yīng)用最廣泛的幾種計(jì)算機(jī)語言之一。 C語言主要有以下一些特點(diǎn):(1)語言表達(dá)能力強(qiáng)。(2)語言簡潔、緊湊,使用靈活,易于學(xué)習(xí)和使用。(3)數(shù)據(jù)類型豐富,具有很強(qiáng)的結(jié)構(gòu)化控制語句。(4)語言生成的代碼質(zhì)量高。(5) 語法限制不嚴(yán)格,程序設(shè)計(jì)自由度大。(6)可移植性好。第2章 概要設(shè)計(jì)21 方案設(shè)計(jì)本課題的任務(wù)是完成一個C源程序的自動評判系統(tǒng)。首先需要解決的問題是確定整個系統(tǒng)的開發(fā)環(huán)境和工作方式,然后是確定系統(tǒng)所要達(dá)到的目標(biāo),接著分析系統(tǒng)所應(yīng)完成的功能以及可能遇到的問題,最后給出具體實(shí)現(xiàn)的步驟。2.1.1 開發(fā)環(huán)境經(jīng)過與指導(dǎo)老師的交流,查閱有關(guān)資料,分析系統(tǒng)的整體情況,本系統(tǒng)更加類似于一個應(yīng)用程序,再結(jié)合自己所學(xué)知識,決定采用微軟的Visual C+集成開發(fā)環(huán)境來開發(fā)整個程序。Visual C+是Windows環(huán)境下最強(qiáng)大、最流行的程序設(shè)計(jì)語言之一。Visual C+可以用來開發(fā)各種類型、不同規(guī)模和復(fù)雜程度的應(yīng)用程序,開發(fā)效率很高,生成的應(yīng)用軟件代碼品質(zhì)優(yōu)良。2.1.2 工作方式分析整個系統(tǒng),最主要的功能是:編譯鏈接源程序,運(yùn)行目標(biāo)程序,目標(biāo)程序輸入輸出的重定向。結(jié)合Visual C+開發(fā)環(huán)境來看,有批處理方式、普通應(yīng)用程序方式、Add-in方式。考慮到Add-in的方式在使用Visual C+編譯器去編譯鏈接C源程序的時候更加方便,并且Add-in的方式也可以利用Visual C+的可視化界面的開發(fā)功能,所以工作方式采用Visual C+下的Add-in方式。Visual C+ Add-In基本上就是實(shí)現(xiàn)了IDSAddIn接口的COM對象。通過這個接口,Add-in能夠掌管Visual C+環(huán)境,并且執(zhí)行特定的任務(wù),例如在Visual C+環(huán)境下打開工作空間,編譯工程等等。在使用Add-in方式的時候,首先需要打開Visual C+環(huán)境,然后加載add-in文件(*.dll)。2.1.3 系統(tǒng)目標(biāo)本系統(tǒng)最終目的是為了減輕老師負(fù)擔(dān),利用計(jì)算機(jī)自動評判編程作業(yè),替代手工檢查方式。要求學(xué)生將編寫好的作業(yè)交至指定文件夾,然后老師運(yùn)行本系統(tǒng),編譯鏈接,運(yùn)行生成目標(biāo)程序,通過比較程序輸出與標(biāo)準(zhǔn)答案,可以得到每個源程序的評判結(jié)果。22 系統(tǒng)功能詳細(xì)的分析整個系統(tǒng)功能應(yīng)該包括:1. 從文件夾抽取源程序。2. 控制Visual C+編譯器編譯鏈接源程序。3. 以測試數(shù)據(jù)運(yùn)行生成的目標(biāo)程序。4. 程序輸出與標(biāo)準(zhǔn)輸出比較。5. 根據(jù)比較結(jié)果得到評判結(jié)果。23 需要解決問題1. 存放C源程序的文件夾的組織方式和文件夾中C源程序的命名方式。2. 程序通過何種方式提取C源程序。3. 用程序控制Visual C+編譯器去編譯鏈接C源程序。4. 如何處理編譯鏈接時出錯,沒有生成目標(biāo)程序的C源程序。5. 通過何種方式運(yùn)行編譯鏈接之后生成的目標(biāo)程序。6. 在運(yùn)行目標(biāo)程序時,如何自動完成目標(biāo)程序的輸入和輸出。7. 對于運(yùn)行目標(biāo)程序時異常情況的處理。8. 采用何種方式比較輸出結(jié)果和正確答案,以及如何存儲比較結(jié)果。24 系統(tǒng)流程2.4.1 基本流程基本上本系統(tǒng)是一個順序執(zhí)行的過程,系統(tǒng)的實(shí)現(xiàn)也是一步一步來的。下一個模塊需要用到上一個模塊的數(shù)據(jù)。系統(tǒng)流程圖如圖1-1所示。1. 系統(tǒng)從文件夾提取出所有的C源程序。2. 系統(tǒng)控制Visual C+的編譯器去編譯鏈接提取出的C源程序,得到相應(yīng)的生成的目標(biāo)程序(exe)。3. 系統(tǒng)以正確輸入數(shù)據(jù)運(yùn)行生成的目標(biāo)程序(exe)。4. 系統(tǒng)提取運(yùn)行目標(biāo)程序(exe)得到的輸出數(shù)據(jù)。5. 系統(tǒng)將輸出數(shù)據(jù)與正確答案進(jìn)行比較。6. 根據(jù)比較結(jié)果得到評判結(jié)果。圖1-1 系統(tǒng)流程圖2.4.2 具體實(shí)現(xiàn)根據(jù)系統(tǒng)應(yīng)該完成的功能,結(jié)合需要解決的問題,系統(tǒng)的具體實(shí)現(xiàn)如下:1. 文件夾的組織方式:每一個題目設(shè)置一個文件夾,同一題目的所有編程作業(yè)(只交后綴名為*.c的文件)交至對應(yīng)的唯一文件夾下。2. 每個文件夾中C源程序的命名方式:以學(xué)號命名,后綴名為*.c,這樣每個文件夾中的C源程序是唯一的,在評判時能更直觀的得到結(jié)果。3. 設(shè)置一個基本對話框,通過列表控件來提取選擇的一個文件夾下的所有C源程序。4. 編譯鏈接方面,Visual C+不能直接編譯鏈接后綴名為*.c的C源程序,因此提前新建一個WIN32空白工程文件,然后將C源程序的后綴名改為*.cpp,放至空白工程中,便可以解決不能直接編譯鏈接的問題。通過Add-in接口,控制整個Visual C+環(huán)境,打開已放入改了后綴名的C源程序的空白工程文件,然后便可進(jìn)行編譯鏈接。在這里要設(shè)置循環(huán),對列表框中的每一個C源程序都進(jìn)行編譯鏈接。5. 循環(huán)過程中,編譯鏈接后生成目標(biāo)程序的C源程序,從空白工程文件的Debug文件夾中復(fù)制其目標(biāo)程序到暫存的文件夾,并用其學(xué)號來命名生成的目標(biāo)程序。然后循環(huán)繼續(xù)直到所有C源程序都完成編譯鏈接。6. 對于編譯鏈接后沒有生成目標(biāo)程序的C源程序,視為編譯鏈接錯誤,將此結(jié)果先一步存至評判結(jié)果處。7. 編譯鏈接全部完成后,設(shè)置彈出一個對話框,用于輸入測試數(shù)據(jù)、運(yùn)行正確的目標(biāo)程序,得到正確答案。同時通過列表框提取已經(jīng)生成的所有以學(xué)號命名的目標(biāo)程序。8. 對于編譯鏈接正確,已經(jīng)生成的目標(biāo)程序,設(shè)置循環(huán),每次循環(huán)中通過新建一個進(jìn)程來運(yùn)行應(yīng)用程序,如果程序正常結(jié)束,則關(guān)閉進(jìn)程,循環(huán)繼續(xù)去運(yùn)行下一個目標(biāo)程序。9. 在運(yùn)行目標(biāo)程序時,通過管道技術(shù)來完成輸入輸出數(shù)據(jù)的重定向問題。10. 對于目標(biāo)程序運(yùn)行時可能出現(xiàn)的種種異常情況,例如死循環(huán)等,通過設(shè)定一個時間,超出這個時間后進(jìn)程強(qiáng)制結(jié)束來處理,進(jìn)程強(qiáng)制結(jié)束后主循環(huán)繼續(xù),同時判定為運(yùn)行時錯誤。11. 在開始循環(huán)運(yùn)行所有目標(biāo)程序之前,需要老師首先運(yùn)行此題目正確程序生成的應(yīng)用程序,并且輸入運(yùn)行數(shù)據(jù)(如無需數(shù)據(jù)輸入則省略此步驟),得到正確的輸出數(shù)據(jù),存入一個編輯框。然后每次運(yùn)行生成的目標(biāo)程序得到輸出時與編輯框中字符串比較,來得到比較結(jié)果。結(jié)果是相同或是不同。12. 最后的評判結(jié)果:沒有生成目標(biāo)程序,判為編譯鏈接出錯-50分;生成了目標(biāo)程序,但是輸出與正確答案不同,判為運(yùn)行錯誤-60分;生成了目標(biāo)程序,并且輸出結(jié)果與正確答案相同,判為程序正確-100分。第3章 詳細(xì)設(shè)計(jì)31 系統(tǒng)模塊化分根據(jù)系統(tǒng)所應(yīng)該完成的功能,以及考慮到使用的方便性,將系統(tǒng)劃分為三個模塊,其中包括兩個基本對話框和一個函數(shù)。3.1.1 添加文件對話框此對話框需要完成的功能、遇到的問題及解決辦法:1. 初始化:在系統(tǒng)運(yùn)行之前刪除空白工程文件中不需要的文件,清空相關(guān)的文件夾。此功能通過對話框上的一個“初始化”按鈕完成。在系統(tǒng)運(yùn)行選擇C源程序文之前,需要對相關(guān)文件夾和文件進(jìn)行處理,有刪除文件夾、清空文件夾、刪除文件。而在Visual C+中是不能直接刪除非空的文件夾的,也沒有清空文件夾的函數(shù),文件是可以通過庫函數(shù)DeleteFile()直接刪除的。因此這里需要自己添加函數(shù)來清空文件夾,在清空文件夾之后調(diào)用庫函數(shù)RemoveDirectory()來刪除已空文件夾。2. 添加文件:初始化之后,從相應(yīng)的存放相同題目的文件夾中提取所有的C源程序文件(過濾器設(shè)置為只能選取后綴名為*.c的文件),將所有的文件添加至對話框的一個列表控件中,列表控件的每一行項(xiàng)目為C源程序文件的絕對路徑。完成添加C源程序后,取得項(xiàng)目總數(shù)的信息存入注冊表,并且以項(xiàng)目總數(shù)設(shè)置循環(huán),將每個C源程序文件的絕對路徑信息存入注冊表,然后調(diào)用編譯鏈接函數(shù)。此功能通過對話框的一個“添加文件”按鈕和一個列表控件完成。在添加文件時選擇用列表控件的方式,這樣在之后設(shè)置循環(huán)對每個C源程序文件進(jìn)行操作時比較方便。同時每個項(xiàng)目中取的是C源程序文件的絕對路徑(包括文件名),因?yàn)橹蟮暮枚嗖僮餍枰募穆窂?,取得學(xué)號信息時也比較方便。因?yàn)樵贏dd-in方式下,對話框類和Add-in類之間的數(shù)據(jù)傳遞比較特殊,所以采用將列表控件中的相關(guān)信息存至注冊表的方式,以便今后在編譯鏈接時調(diào)用。3. 確認(rèn):新建對話框時,默認(rèn)的代碼,無實(shí)際功能。通過點(diǎn)擊此按鈕,得到“OK”按鈕按下的消息,調(diào)用編譯鏈接函數(shù)。通過對話框的“OK”按鈕完成。此對話框的數(shù)據(jù)輸入是:文件夾中選取的所有后綴名為(*.c)的C源程序文件。此對話框的數(shù)據(jù)輸出是:列表控件中的項(xiàng)目總數(shù)和列表控件每個項(xiàng)目中C源程序文件的絕對路徑。3.1.2 編譯鏈接函數(shù)此函數(shù)需要完成的功能、遇到的問題及解決辦法:編譯鏈接:從注冊表提取出添加文件對話框中列表控件的項(xiàng)目總數(shù),以此設(shè)置循環(huán)。在每次循環(huán)中,首先進(jìn)行初始化操作,刪除空白工程文件夾中相關(guān)不用的文件和文件夾,然后通過從注冊表提取出添加文件對話框列表控件的項(xiàng)目中的C源程序文件的絕對路徑,將后綴名為*.c的C源程序文件改名為與建立空白工程時建立的關(guān)聯(lián)的*.cpp文件。通過Add-in的接口,在Visual C+工作空間打開空白工程文件,此時它已經(jīng)成為C源程序文件的工程文件,進(jìn)行編譯鏈接。編譯鏈接完成之后如果在空白工程文件的Debug文件夾中找到生成的目標(biāo)程序,則以此C源程序文件中的學(xué)號信息來命名此目標(biāo)程序(即,此時目標(biāo)程序改名為學(xué)號.exe)并且將改名后的目標(biāo)程序復(fù)制到暫存所有生成的目標(biāo)程序的文件夾中,以備運(yùn)行時使用。而如果編譯鏈接完成之后在空白工程文件的Debug文件夾中沒有找到生成的目標(biāo)程序,則視為編譯鏈接錯誤,直接在結(jié)果文件夾中以學(xué)號為信息給出評判結(jié)果。處理結(jié)束后進(jìn)行下一個循環(huán)直到循環(huán)結(jié)束,給出編譯鏈接已完成的信息提示框。首先編譯鏈接時取用的數(shù)據(jù)是剛才添加文件對話框中列表控件中添加入注冊表的信息。在每次循環(huán)開始前,都需要對test文件夾進(jìn)行處理,刪除Debug文件夾,刪除0.cpp文件,清空result、outcome文件夾,這些問題同添加文件對話框問題中的初始化一樣,都需要自己編寫函數(shù)來清空文件夾和刪除非空文件夾。然后因?yàn)槭菍源程序文件加入空白工程文件中編譯,且空白的關(guān)聯(lián)cpp文件已經(jīng)命名為0.cpp,所以C源程序文件在編譯鏈接前都需要改名為0.cpp文件。之后通過Add-in,控制整個Visual C+的開發(fā)環(huán)境,首先打開工作空間,然后載入工程,之后編譯鏈接,當(dāng)然這些都是Visual C+自動完成的,相當(dāng)于按下了Build按鈕,這也就是使用Add-in方式的關(guān)鍵所在。編譯鏈接結(jié)束后,如果在Debug文件夾中生成0.exe文件,則視為編譯鏈接成功,且此時需要將此文件轉(zhuǎn)移出來,因?yàn)槿绮晦D(zhuǎn)移,編譯鏈接下一個C源程序文件時會覆蓋此0.exe文件。此函數(shù)的數(shù)據(jù)輸入是:列表控件中的項(xiàng)目總數(shù)和列表控件每個項(xiàng)目中C源程序文件的絕對路徑。此函數(shù)的數(shù)據(jù)輸出是:編譯鏈接成功后以學(xué)號命名的存至相同文件夾下的目標(biāo)程序;編譯鏈接錯誤后以學(xué)號為區(qū)分信息的存至結(jié)果文件夾下的評判結(jié)果。3.1.3 運(yùn)行/評判對話框此對話框需要完成的功能及其解決辦法:1. 輸入數(shù)據(jù)、運(yùn)行正確程序:彈出此對話框后,進(jìn)入運(yùn)行目標(biāo)程序,評判階段,首先運(yùn)行此題目正確程序編譯鏈接后生成的exe程序,如果需要輸入數(shù)據(jù)才能運(yùn)行的,先輸入數(shù)據(jù),得到此題目正確的輸出。此功能通過“選擇正確程序”按鈕來選擇此題目正確程序生成的exe文件,通過一個編輯框顯示運(yùn)行的正確exe文件路徑,通過另一個編輯框來實(shí)現(xiàn)數(shù)據(jù)輸入,通過第三個編輯框來得到運(yùn)行正確exe文件后得到的數(shù)據(jù)輸出,即標(biāo)準(zhǔn)答案。在編譯鏈接結(jié)束后,進(jìn)入運(yùn)行/評判階段,首先需要運(yùn)行正確的程序,這是老師之前通過編譯鏈接正確題目程序得到的正確的exe程序。如果程序需要輸入數(shù)據(jù)之后運(yùn)行的,在“正確輸入”編輯框中輸入正確數(shù)據(jù)。通過編輯框的方式輸入數(shù)據(jù)方便直觀。因?yàn)檫@里是老師輸入正確程序的正確數(shù)據(jù)輸入,所以老師會確保輸入數(shù)據(jù)的正確性。而如果不需輸入數(shù)據(jù)即可得到輸出數(shù)據(jù)的話就不用輸入數(shù)據(jù)即可。之后通過CreateProcess()函數(shù)運(yùn)行正確程序,這里通過重定向技術(shù)使用管道來完成自動的使用輸入數(shù)據(jù)運(yùn)行程序并且自動的將輸出數(shù)據(jù)送入編輯框而不是在顯示屏顯示。在正確輸出編輯框中會顯示出正確的結(jié)果,這樣子也便于觀察。2. 選擇目標(biāo)文件:輸入正確數(shù)據(jù),以此數(shù)據(jù)運(yùn)行正確的exe文件后,得到正確輸出,即標(biāo)準(zhǔn)答案。選取暫存文件夾中所有C源程序文件編譯鏈接正確后生成的所有以學(xué)號命名的目標(biāo)程序至列表控件,列表控件項(xiàng)目為選取的目標(biāo)程序的絕對路徑。此功能通過一個“添加文件”完成選取所有目標(biāo)程序,通過一個列表控件來完成添加所有目標(biāo)文件。這里也是通過列表控件來完成選擇文件的工作,因?yàn)橹郎傻乃心繕?biāo)程序在test文件夾下的result文件夾中,所以在打開文件時直接定位到此程序所在的文件夾。每個項(xiàng)目中同樣也是放的目標(biāo)程序的絕對路徑(包括文件名),因?yàn)橹笫褂煤瘮?shù)運(yùn)行程序是需要使用程序的絕對路徑。3. 運(yùn)行目標(biāo)文件、進(jìn)行評判:完成選取所有目標(biāo)程序后,以列表控件的項(xiàng)目總數(shù)即目標(biāo)程序總數(shù)設(shè)置循環(huán)。在每次循環(huán)中,以運(yùn)行正確程序的exe文件時的數(shù)據(jù)輸入作為運(yùn)行目標(biāo)程序的數(shù)據(jù)輸入,即使用正確輸入編輯框中的輸入數(shù)據(jù),去運(yùn)行目標(biāo)程序,得到輸出數(shù)據(jù),將此輸出數(shù)據(jù)與正確輸出編輯框中的數(shù)據(jù)比較,這兩個數(shù)據(jù)都是CString類型的。如果比較結(jié)果相同,則視為運(yùn)行正確,將此結(jié)果以學(xué)號信息為區(qū)別存至結(jié)果文件夾中作為評判結(jié)果;如果比較結(jié)果不同,則視為運(yùn)行時錯誤,也將此結(jié)果以學(xué)號信息為區(qū)別存至結(jié)果文件夾作為評判結(jié)果。完成一個目標(biāo)程序的運(yùn)行、評判之后,循環(huán)繼續(xù),去運(yùn)行、評判下一個C源程序。直到處理完所有的目標(biāo)程序,至此運(yùn)行、評判結(jié)束。此功能通過一個“開始”按鈕完成。在這里運(yùn)行程序時的原理和運(yùn)行正確程序時的一樣,正確的數(shù)據(jù)輸入就采用正確輸入編輯框中的數(shù)據(jù),這樣可以確保程序正確時得到的輸出與正確輸出相同,方便評判。一個問題是需要考慮到這里運(yùn)行的是學(xué)生的程序而不是老師的正確程序,所以可能出現(xiàn)運(yùn)行異常、死循環(huán)的進(jìn)程不結(jié)束的問題,那么就會出現(xiàn)死機(jī)的情況,主程序運(yùn)行不下去,所以這里需要設(shè)置進(jìn)程運(yùn)行超時的處理。因?yàn)槭墙虒W(xué)中的C源程序文件作業(yè),相對較為簡單,所以設(shè)置運(yùn)行時間為4秒,如果進(jìn)程運(yùn)行超時還沒有自動結(jié)束,則強(qiáng)制結(jié)束,判為運(yùn)行時錯誤。若果進(jìn)程自動結(jié)束,則于正確結(jié)果比較得到評判結(jié)果。此對話框的數(shù)據(jù)輸入是:題目正確源程序生成的exe文件,正確的測試數(shù)據(jù)輸入,所有C源程序文件編譯鏈接正確后生成的目標(biāo)程序。此對話框的數(shù)據(jù)輸出是:以輸入的正確測試數(shù)據(jù)運(yùn)行正確程序后的正確數(shù)據(jù)輸出;比較運(yùn)行目標(biāo)程序后的數(shù)據(jù)輸出與正確數(shù)據(jù)輸出,結(jié)果相同后得到的以學(xué)號信息區(qū)別的存至結(jié)果文件夾的運(yùn)行正確的評判結(jié)果;比較運(yùn)行目標(biāo)程序后的數(shù)據(jù)輸出與正確數(shù)據(jù)輸出,結(jié)果不同后得到的以學(xué)號信息區(qū)別的存至結(jié)果文件夾的運(yùn)行錯誤的評判結(jié)果。32 系統(tǒng)模塊具體實(shí)現(xiàn)在這一節(jié)中,將會對各個模塊中系統(tǒng)那個實(shí)現(xiàn)的難點(diǎn)、遇到的問題、解決的方法、重點(diǎn)技術(shù)問題的給出詳細(xì)的說明。3.2.1 準(zhǔn)備工作在開始系統(tǒng)設(shè)計(jì)之前,在Visual C+中新建一個Win32空白工程,這里工程名為test,然后在此空白工程中新建一個C+文件,文件名為0.cpp。以后編譯鏈接選取的C源程序文件時則將C源程序文件改名為0.cpp并替換空白工程中的0.cpp文件即可。為防止編譯鏈接時編譯鏈接兩次,選擇組件-配置,移除Win32 Release只保留Win32 Debug。在此空白工程文件夾test中,新建一個文件夾result用于保存編譯鏈接成功后生成的以學(xué)號命名的目標(biāo)程序,新建一個文件夾outcome用于存放最后的評判信息,新建一個空白文本文件file.txt。在每次開始使用系統(tǒng)之前,進(jìn)行的初始化操作就包括刪除Debug文件夾、刪除0.cpp文件,清空result和outcome文件夾。接著開始系統(tǒng)的具體功能實(shí)現(xiàn)階段。首先Visual C+中新建一個DevStudio Add-in Wizard工程,工程名稱為Auto,并且在CCommands-ICommands中自動添加一個函數(shù)AutoCommandMethod()。這個函數(shù)是系統(tǒng)的切入點(diǎn)。這時編譯鏈接工程之后,生成DLL文件,加載此文件后,工具欄會添加一個按鈕,此按鈕實(shí)現(xiàn)的是AutoCommandMethod()的函數(shù)功能。系統(tǒng)的使用從點(diǎn)擊這個按鈕開始。3.2.2 實(shí)現(xiàn)添加文件對話框建立起DevStudio Add-in Wizard工程后,在工作空間,右擊Auto Classes添加一個對話框類AddFile,即添加文件對話框。編輯此對話框,添加“初始化”、“添加文件”按鈕和一個列表控件,保留默認(rèn)的“OK”、“Cancle”按鈕。1. “初始化”按鈕:此按鈕完成的功能是刪除Debug文件夾、刪除0.cpp文件,清空result和outcome文件夾。在Visual C+中可以通過庫函數(shù)DeleteFile()刪除一個文件。(1). 在此遇見的問題是在Visual C+中不能直接刪除一個不為空的文件夾以及沒有現(xiàn)成的庫函數(shù)來清空一個文件夾,因此自己添加兩個函數(shù)DeleteFolder和ClearFolder,分別用于刪除文件夾(不管其是否為空)和清空文件夾(清空其中的文件而保留文件夾),函數(shù)代碼如下:a. DeleteFolder函數(shù)void AddFile:DeleteFolder(CString sPath) CFileFind ff; BOOL bFound; bFound = ff.FindFile(sPath + *.*); while(bFound) bFound = ff.FindNextFile(); CString sFilePath = ff.GetFilePath(); if(ff.IsDirectory() if(!ff.IsDots() DeleteFolder(sFilePath); else if(ff.IsReadOnly() SetFileAttributes(sFilePath, FILE_ATTRIBUTE_NORMAL); DeleteFile(sFilePath); ff.Close(); SetFileAttributes(sPath, FILE_ATTRIBUTE_NORMAL); RemoveDirectory(sPath); b. ClearFolder函數(shù)void AddFile:ClearFolder(CString sPath) CFileFind ff; BOOL bFound; bFound = ff.FindFile(sPath + *.*); while(bFound) bFound = ff.FindNextFile(); CString sFilePath = ff.GetFilePath(); if(ff.IsDirectory() if(!ff.IsDots() DeleteFolder(sFilePath); else if(ff.IsReadOnly() SetFileAttributes(sFilePath, FILE_ATTRIBUTE_NORMAL); DeleteFile(sFilePath); ff.Close(); SetFileAttributes(sPath, FILE_ATTRIBUTE_NORMAL); (2). 完整的“初始化”按鈕代碼如下:CString StrDestFile=D:test0.cpp;DeleteFile(StrDestFile);/刪除0.cpp文件 CString DirectoryDebugName=D:testDebug;DeleteFolder(DirectoryDebugName);/刪除DEBUG文件夾CString DirectoryResultName=D:testresult;ClearFolder(DirectoryResultName);/清空result文件夾ClearFolder(D:testoutcome);/清空outcome文件夾GetDlgItem(IDC_addfile_BUTTON)-EnableWindow(true);/設(shè)置“添加文件”按鈕禁用,點(diǎn)擊“初始化”后啟用GetDlgItem(IDOK)-EnableWindow(true);/設(shè)置“OK”按鈕禁用,點(diǎn)擊“初始化”后啟用2. “添加文件”按鈕:點(diǎn)擊之后彈出選擇文件對話框,完成選擇所有的C源程序文件,然后將所有的C源程序文件添加至對話框的列表控件中,列表控件的每一行項(xiàng)目為C源程序文件的絕對路徑。然后將列表控件中的項(xiàng)目總數(shù)和每個項(xiàng)目所指向的C源程序文件的絕對路徑存入注冊表,以備編譯鏈接時使用。(1). 列表控件的初始化工作需要首先設(shè)置列表控件的屬性屬性-樣式-查看-報(bào)告,然后在AddFile類的Message中選擇WM_INITDIALOG添加函數(shù)OnInitDialog(),最后在此函數(shù)中添加代碼如下:m_list.InsertColumn(0,file,LVCFMT_CENTER,500,-1);(2). 點(diǎn)擊“添加文件”按鈕后彈出打開文件對話框,通過CFileDialog來實(shí)現(xiàn),設(shè)置過濾器以便只能選擇后綴名為*.c的C源程序文件,同時相關(guān)參數(shù)設(shè)置為能夠選擇多個文件,其代碼如下:CFileDialog Dlg(TRUE,*.c,NULL,OFN_FILEMUSTEXIST|OFN_ALLOWMULTISELECT,C文件(*.c)|*.c|,NULL);(3). 對于選擇多個文件添加至列表控件中,需要設(shè)置指針,通過GetStartPosition()函數(shù)使指針指向選取的第一個文件開始,直至最后一個文件,然后通過GetNextPathName()函數(shù)來將選取的C源程序文件的絕對路徑添加入列表控件,代碼如下:POSITION pos=Dlg.GetStartPosition(); while(pos!=NULL) CString FileName=; FileName = Dlg.GetNextPathName(pos); m_list.InsertItem(0, , 0);m_list.SetItem(0, 0, LVIF_TEXT, FileName,0, 0, 0, 0); (4). 將選取的所有C源程序文件的絕對路徑存入列表控件后,通過AfxGetApp()-WriteProfileInt將列表框項(xiàng)目總數(shù)寫入注冊表,然后以項(xiàng)目總數(shù)設(shè)置循環(huán),通過AfxGetApp()-WriteProfileString依次將每個C源程序文件的絕對路徑寫入注冊表,以備編譯鏈接時使用,其代碼如下:AfxGetApp()-WriteProfileInt(Configure, count,m_list.GetItemCount();for (int i = 0 ; i WriteProfileString(Configure, szRegKey,m_list.GetItemText(i, 0);(5). 完整的“添加文件”按鈕代碼如下:CFileDialog Dlg(TRUE,*.c,NULL,OFN_FILEMUSTEXIST|OFN_ALLOWMULTISELECT,C文件(*.c)|*.c|,NULL);if(Dlg.DoModal()=IDOK) POSITION pos=Dlg.GetStartPosition(); while(pos!=NULL) CString FileName=; FileName = Dlg.GetNextPathName(pos); m_list.InsertItem(0, , 0);m_list.SetItem(0, 0, LVIF_TEXT, FileName,0, 0, 0, 0); AfxGetApp()-WriteProfileInt(Configure, count,m_list.GetItemCount();for (int i = 0 ; i WriteProfileString(Configure, szRegKey,m_list.GetItemText(i, 0); 3. “OK”按鈕:此按鈕的代碼是新建對話框時的默認(rèn)代碼,無實(shí)際功能,其按下的意義在于,取得按下“OK”的消息,調(diào)用編譯鏈接函數(shù)。此消息的實(shí)現(xiàn)是在系統(tǒng)切入點(diǎn)AutoCommandMethod()函數(shù)出,點(diǎn)擊工具欄按鈕后彈出添加文件對話框,進(jìn)行完選取C源程序文件的操作后,點(diǎn)擊“OK”按鈕,AutoCommandMethod()函數(shù)得到按下“OK”按鈕的消息,然后調(diào)用編譯鏈接函數(shù),進(jìn)入下一步工作,這里AutoCommandMethod()函數(shù)相關(guān)代碼如下:AddFile AddFileDlg;/彈出添加文件對話框if(AddFileDlg.DoModal()=IDOK)/若按下添加文件對話框的“OK”按鈕build();/調(diào)用編譯鏈接函數(shù)3.2.3 實(shí)現(xiàn)編譯鏈接函數(shù)首先建立編譯鏈接函數(shù),這個函數(shù)是在Add-in方式下建立的,目的是操控Visual C+的開發(fā)環(huán)境,實(shí)現(xiàn)在工作空間打開工程文件,調(diào)用Visual C+自帶的編譯器去編譯鏈接工程。建立此函數(shù)的過程是:右擊CCommands類下的ICommands,選擇Add Method,然后方法名稱為build,即建立了一個build()函數(shù),此時函數(shù)代碼為空,不實(shí)現(xiàn)功能。 在添加文件對話框完成所有工作后,點(diǎn)擊“OK”按鈕,發(fā)出按鈕按下的消息,在AutoCommandMethod()函數(shù)中調(diào)用build()函數(shù)。此函數(shù)要實(shí)現(xiàn)的功能是:1. 初始化工作,在每次編譯鏈接C源程序文件前需要刪除Debug文件夾和o.cpp文件,以保證編譯鏈接成功后在Debug文件夾中生成的目標(biāo)程序是對應(yīng)當(dāng)前的C源程序文件的,其代碼如下:DeleteFile(D:test0.cpp);/刪除0.cpp文件DeleteFolder(D:testDebug);/刪除Debug文件夾2. 取得C源程序文件中的學(xué)號信息,因?yàn)镃源程序文件存至列表控件中的是其絕對路徑,包括路徑和完整的文件名(因?yàn)樵诿麜r有要求,所以文件名也就是“學(xué)號.c”),所以需要提取出文件名中的學(xué)號(即文件標(biāo)題),學(xué)號是唯一區(qū)別標(biāo)志,以便在給出評判結(jié)果時使用學(xué)號信息,代碼如下:CString stillfilename;CString filetitle;CString StrFile=AfxGetApp()-GetProfileString(Configure, RegKey, );/獲取文件路徑和完整文件名 stillfilename=StrFile.Right(StrFile.GetLength()-StrFile.ReverseFind()-1);/獲取文件名,帶后綴filetitle=stillfilename.Left(stillfilename.ReverseFind(.);/獲 取文件標(biāo)題(學(xué)號),即文件名去掉后綴3. 取得注冊表中存入的添加文件對話框中列表控件的項(xiàng)目總數(shù)和每個項(xiàng)目中選取的C源程序文件的絕對路徑,并以項(xiàng)目總數(shù)設(shè)置循環(huán)。每次循環(huán)中首先進(jìn)行初始化操作,然后將C源程序文件改名為o.cpp文件并復(fù)制到空白工程test文件夾下。新打開一個工作空間,打開此時的test工程文件(test.dsw),最后編譯鏈接此工程文件。(1). 取得項(xiàng)目總數(shù),并以此設(shè)置循環(huán)的代碼如下:int nNumWorkspaces=AfxGetApp()-GetProfileInt(Configure,count,0);for (int nWorkspaceNumber = nNumWorkspaces;nWorkspaceNumber = 1;nWorkspaceNumber-)(2). 改名復(fù)制C源程序文件,新建工作空間,打開工程文件,編譯鏈接的代碼如下:long lCount; char RegKey50;wsprintf(RegKey, %d, nWorkspaceNumber-1);CString StrDestFile=D:test0.cpp;CopyFile(StrFile,StrDestFile,false);/拷貝并改名C文件至空白工程CComBSTR bszWorkspacePathName = D:testtest.dsw;CComPtr pDispDocuments;VERIFY_OK(m_pApplication-get_Documents(&pDispDocuments);CComVariant OleVariant; CComQIPtr pDocuments(pDispDocuments);CComPtr pWorkspace;VERIFY_OK(pDocuments-Open(bszWorkspacePathName, OleVariant,OleVariant, &pWorkspace);CComPtr pDispProjects;VERIFY_OK(m_pApplication-get_Projects(&pDispProjects);CComQIPtr pProjects(pDispProjects);VERIFY_OK(pProjects-get_Count(&lCount);for (long i = 1 ; i lCount+1 ; i+)long lNumConfigs;CComVariant Vari = i;CComPtr pGenProject;VERIFY_OK(pProjects-Item(Vari, &pGenProject);CComQIPtrpProject(pGenProject);CComPtr pConfigs;VERIFY_OK(pProject-get_Configurations(&pConfigs);VERIFY_OK(pConfigs-get_Count(&lNumConfigs);for (long j = 1 ; j lNumConfigs+1 ; j+)CComVariant Varj = j;CComPtr pConfig;VERIFY_OK(pConfigs-Item(Varj, &pConfig);CComVariant VarDisp = pConfig;CComBSTR bszStr;VERIFY_OK(pConfig-get_Name(&bszStr);VERIFY_OK(m_pApplication-Build(VarDisp);(3). 在循環(huán)中遇到的問題是每次打開一個工作空間并對工程進(jìn)行編譯鏈接后沒有關(guān)閉文檔,從而使每次開始新循環(huán)后無法實(shí)現(xiàn)刪除Debug文件夾和o.cpp文件,造成目標(biāo)程序永遠(yuǎn)是對應(yīng)第一個C源程序文件的,解決的辦法是在編譯鏈接結(jié)束后關(guān)閉文檔,即工作空間,代碼如下:DsSaveStatus d;VARIANT vtSaveChanges;vtSaveChanges.lVal=dsSaveChangesNo;vtSaveChanges.vt=VT_I4;VERIFY_OK(pDocuments-CloseAll(vtSaveChanges,&d);4. 每次循環(huán)中,編譯鏈接結(jié)束后,關(guān)閉工作空間,在空白工程test文件夾中的Debug下,如果能找到生成的目標(biāo)程序test.exe文件,則視為編譯鏈接正確,將此test.exe文件復(fù)制到暫存目標(biāo)程序的result文件夾,并改名為以學(xué)號命名的exe文件,即學(xué)號.exe文件,作為此C源程序文件編譯鏈接成功生成的目標(biāo)程序。而如果編譯鏈接結(jié)束后,在Debug文件夾中沒有找到生成的目標(biāo)程序test.exe文件,則視為編譯鏈接錯誤,復(fù)制空白的文本文件file.txt并改名為以此C源程序文件的學(xué)號命名的“學(xué)號-編譯錯誤-50”文本文件,作為評判結(jié)果存至結(jié)果文件夾outcome。這一部分代碼如下:CFileFind find;CFileFind findexe;if(find.FindFile(exefile)CopyFile(exefile,D:testresulttest.exe,false); if(findexe.FindFile(D:testresulttest.exe) CString newexefile=D:testresult+filetitle+.exe;MoveFile(D:testresulttest.exe,newexefile); elseCString errorfile;CString file=D:testfile.txt;errorfile=D:testoutcome+filetitle+編譯錯誤-50+.txt;CopyFile(file,errorfile,false);5. 編譯鏈接完所有的C源程序文件,在result文件夾中存儲所有編譯鏈接成功后得到的以學(xué)號命名的目標(biāo)程序,在outcome文件夾中存儲所有編譯鏈接錯誤沒有得到目標(biāo)程序的以學(xué)號為區(qū)別信息的評判結(jié)果之后,彈出消息提示框,提示編譯鏈接已經(jīng)結(jié)束,點(diǎn)擊確認(rèn)進(jìn)入運(yùn)行/評判對話框。代碼如下:CString StrInfo=編譯連接結(jié)束,點(diǎn)擊進(jìn)行運(yùn)行評判;if(AfxMessageBox(StrInfo,MB_YESNO)=IDYES)run RunDlg; /這里run是建立的運(yùn)行/評判對話框的類名RunDlg.DoModal();3.2.4 實(shí)現(xiàn)運(yùn)行/評判對話框調(diào)用編譯鏈接函數(shù),對所有的C源程序文件進(jìn)行編譯鏈接,處理生成的目標(biāo)文件,并且先一步給出編譯鏈接不正確的C源程序文件的評判結(jié)果后,彈出運(yùn)行/評判對話框。這就首先需要在工作空間,右擊Auto Classes添加一個對話框類run,即添加運(yùn)行/評判對話框。編輯此對話框,首先添加一些必要的用于說明性的靜態(tài)文本,再添加編輯框一用于顯示運(yùn)行的正確的exe程序絕對路徑;編輯框二用于輸入運(yùn)行正確程序的輸入數(shù)據(jù),此數(shù)據(jù)也用于作為運(yùn)行所有生成的目標(biāo)程序的輸入數(shù)據(jù);編輯框三用于輸出運(yùn)行正確exe程序后的正確輸出結(jié)果,并且在運(yùn)行所

溫馨提示

  • 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. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論