趙中堂,劉明勛
(1鄭州航空工業管理學院智能工程學院 河南 鄭州 450046)
(2北京理工大學智能機器人與系統高精尖創新中心 北京 100081)
學習C、C++語言時,需要進行大量的練習[1-2]。對于初學者來說選擇一個簡潔易懂、容易使用的集成開發環境將對后續的學習提供巨大的幫助。經過對多個流行的文本編輯器及集成開發環境(integrated development environment,IDE)滿意度調研發現,許多初學者對于這些代碼編輯器并不滿意。
(1)對于初學者而言,系統越簡單失誤率越低;系統越復雜,一旦失效所造成的損失也是巨大的,甚至是災難性的。例如,VC++6.0的集成開發環境會因為龐大的軟件體系與鍵盤熱鍵等一系列全新內容而勸退一大批初學者,這無疑增加了學習成本。并不是認為其不優秀,只是復雜的系統并不適合初學者。
(2)初學者需要一個穩定便捷的軟件,簡單如DEV-C++的編譯器,也會因為無人維護等一系列原因,造成軟件崩潰的現象。Notepad++也是一款不錯的代碼編輯軟件,它帶有語法高亮與縮進功能,但是它并不能編譯以及調試C/C++源碼,還是需要借助外部編譯器,顯然這也會增加初學者的負擔。
(3)初學者需要大量的數據測試[3-5],數據測試的效率問題可能是眾多編譯器的通病。據作者統計,許多初學者在做編程練習的時候都有測試數據以檢查代碼正確性的習慣,而目前市面上的編輯器及IDE大多都是編譯后執行命令行,去讓使用者去輸入數據,這將會浪費很大一部分時間。
根據以上缺點分析,本文設計了一個方便易用的C/C++的源代碼編譯測試系統,只需要用戶輸入待測試源碼、測試數據及預期輸出,就可以對該源碼進行多次帶有正誤反饋的測試結果,多次使用證明可以極大減少測試的時間。
在設計該系統時,參考并改良了一些測試系統[6],本系統成品界面見圖1。
從圖1所示界面,點擊文件菜單,在出現的下拉菜單中點擊新建菜單項,或者直接使用快捷鍵Ctrl+N,就會彈出一個新的子窗體,老的子窗體并不會消失。若想關閉當前子窗體,可以點擊窗體右上角的關閉按鈕,也可以通過文件菜單的“關閉”菜單項關閉。

圖1 編譯測試系統主界面
在彈出的“C++編譯調試器”窗口中,就是我們要操作的部分。在左邊第一個文本框中粘貼或者通過鍵盤輸入C、C++程序代碼,在“測試輸入數據”提示下面的文本框中輸入用戶的測試數據,在“預期輸出數據”提示下面的文本框中輸入標準答案[7]。然后點擊右上方的“編譯運行”按鈕,程序會把源碼編譯后自動執行并輸入測試數據,執行結果將與其預期輸出進行對比。如果編譯不通過,編譯器輸出欄將以黑底紅字顯示編譯器報錯結果;如果編譯通過且執行結果與預期結果相同,運行結果欄將正常顯示執行結果;如果執行結果與預期結果不相同,運行結果欄將以紅底黑字顯示出來。
程序的執行流程見圖2。

圖2 程序執行流程圖
本系統所使用的開發工具為微軟公司的產品Visual Studio2019,基于.Net Framework框架,利用C#語言的WinForm技術制作[8,10]。
本系統所使用到的技術有:C#桌面應用開發、MDI(Multiple Document Interface,多文檔界面)、文件操作、進程調用、C/C++程序編譯原理。
從圖1可以看出,該系統界面簡潔,所使用的窗體控件有窗體Form、標簽控件Label、文本框控件TextBox、按鈕控件Button,并調整了相關控件的相應屬性,使它更符合使用習慣。設置左邊3個文本框的背景為白色,字體為黑色,允許用戶向其中粘貼代碼和數據,也允許通過鍵盤輸入數據;設置代碼輸入文本框為等寬字體顯示;設置編譯器輸出文本框和輸出結果文本框為灰色背景,只讀屬性,不允許用戶向其中輸入數據。
使用主界面MDI屬性,創建MDI窗體[9],并設定子窗體的MDI父窗體為主界面;從菜單欄中新建選項即可創建新的測試窗體。
在點擊“編譯運行”按鈕后,程序File類的open方法打開代碼文件tempCode.cpp,建立FileStream文件流[10]對象。通過創建StreamWriter對象將代碼文本框中的代碼存入到該文件中,覆蓋掉原有內容;如果該文件不存在,則創建該文件并寫入代碼。參考代碼如下:
privatevoidWriteFile(string code) {
string path = “tempCode.cpp”;
FileStream fs=File.Open(path,FileMode.Create);
StreamWritersw = newStreamWriter(fs);
sw.WriteLine(code);
sw.Flush();
sw.Close();
fs.Close();
使用保存的C/C++源代碼文件tempCode.cpp,程序調用g++編譯器編譯該源代碼文件。為了使用g++編譯器的功能,需要在控制臺下調用g++,就需要用到C#的進程類Process。
用Process類創建對象p,設置要為控制臺程序cmd.exe創建進程,并設置對應的重定向標準輸入、標準輸出、標準錯誤等屬性,然后啟動進程。參考代碼如下:
Process p = newProcess();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
國內外學者圍繞技術溢出,對合作創新的市場績效進行了系統且細致的研究。但是研究的視角單一,技術溢出僅僅是影響合作創新的主要原因之一,另外實證研究也非常不夠。因此,從以下幾方面加強對合作創新市場績效的研究,對提高我國企業的自主創新動力和效率,發展戰略新興產業,實現創新型國家的目標意義重大。
p.Start();
接下來,模擬在控制臺下輸入編譯指令,調用g++.exe編譯器程序編譯tempCode.cpp源代碼文件。并將編譯信息寫入一個字符串,以備查看。參考代碼如下:
p.StandardInput.AutoFlush = true;
p.StandardInput.WriteLine(""..\..\MinGW64\bin\g++.exe" tempCode.cpp -g -Wall -O2 -staticlibgcc -std=c++14 -pipe -fexec-charset=GBK &exit");
stringcompilerOutput = p.StandardError.ReadToEnd();
當編譯器g++執行完畢,若有錯誤輸出,則把錯誤信息寫入編譯器輸出文本框,等待用戶修訂程序,然后點擊“編譯運行”按鈕。若程序沒有編譯錯誤,則繼續運行,查看程序的正確性。
當程序沒有語法錯誤時,編譯器g++的產出為可執行文件,不失一般性,命名為a.exe。為a.exe創建進程,將測試數據作為標準輸入進程中,并通過標準輸出得到輸出結果,存入一個字符串runOutput中,將runOutput與標準答案進行比較,如果不想等,則是程序存在邏輯錯誤,指示用戶進行改正。
本文針對現有C/C++集成開發工具在開發、測試源代碼程序時,需要多次輸入測試數據的缺點,基于WinForm技術設計了一個專門為初學者打造的高效率編譯測試系統,能夠做到使用戶只需要輸入一次測試數據,就將極大提高開發效率。同時,可以將該功能基于Web系統實現,使得更多的學習者受益。