一、任务
上次的《用Python自动批改C语言作业(二)》提到对于末尾有getch();语句的C程序,Python未能成功自动传给它任意一个按键,导致我们编译和运行C程序时还得人工干预一下,看见黑屏就敲一下回车键。上次提到一个无赖的办法是用return 0;语句来替换掉C程序里面的getch();语句,不过这个毕竟是修改了同学提交的C程序,感觉不太好。这里新再次实验,争取在不改动学生提交的C程序的前提下让getch();语句导致的黑屏自动消失。
二、环境
外甥打灯笼——照旧(舅)。
Win7 32位 + Python3.64 + GCC编译器
三、原因
这里得说一下getchar();和getch();这两个语句的区别。
函数getchar()是标准C的输入函数,只要键盘缓冲区有内容,getchar();语句就能自动从键盘缓冲区获取一个字符。而函数getch()不是标准C的函数,getch();语句需要的数据来源于键盘中断,不能从键盘缓冲区取得数据。
能够从键盘缓冲区获取数据的输入语句都可以用管道为其提供数据,显然getchar();语句可以用管道获取数据,getch();语句就不可以从管道获取数据。因此,自动运行C语言程序编译出来的exe文件时,会出来一个黑屏窗口等着用户按一下键盘,getch();语句才能得到数据从而结束黑屏。
四、思路
网络文章《实现Python虚拟按键解决getch()的自动化测试问题》为了解决这个自动化测试中的getch();问题,自己写了个虚拟键盘的小程序解决了问题。
受该文启发,小编用Python代码实现了一个虚拟按键程序key.py,该程序运行后不断监控黑屏窗口是否出现,如果出现,则向黑屏窗口发送一个虚拟按键,然后就能自动让黑屏窗口消失。
key.py内容如下:

五、代码
自动编译运行C语言程序的Python代码也作了修改,全部代码如下:

六、讨论
这种办法勉强能使自动化批改C语言程序的工作进行下去,好歹算是解决了问题。但该程序有个缺点,只能在IDLE中加载该Python代码来运行,不能在命令行窗口中运行。因为在命令行窗口中运行的话,黑屏窗口的标题就不是编译出来的exe文件的位置这个字符串了,所以会找不到黑屏窗口,无法发送虚拟按键,还得手工消除黑屏窗口。
另外,由于对Python知识和进程管理的知识掌握得不太好,导致写出了两个Python程序来相互配合完成任务。我自己觉得理想的情况是只用一个编译和运行C语言程序的Python程序就能搞定全部工作。但目前来说没有思路了,因为subprocess.Popen尚未运行exe文件的时候,窗口是不存在的,不能提前发送按键,而一旦subprocess.Popen运行了exe文件,Python程序立马变成了阻塞状态,getch();语句就开始起作用,出现黑屏窗口等着按键,根本没有办法再运行别的Python语句给黑屏窗口发送虚拟按键了。想来想去,只能先弄两个Python程序了。
关于自动批改C语言作业的推文,以后或许能出一个《用Python自动批改C语言作业(四)》,或许就到此为止了。




