利用python执行C程序
首先python自己是无法真正意义上地去执行C语言的代码的,但是我们可以转换思路,利用python调用外部程序来实现。
0.配置环境变量
由于需要调用编译器进行程序的编译运行,故需要在环境变量path中添加编译器地址。
如何找到编译器地址?以codeblocks 为例:在 \CodeBlocks\MinGW\bin 目录下有g++.exe,其他编译器自行手动搜索
配置环境变量:此电脑->属性->(左侧栏的)高级系统设置->高级->环境变量
双击Path,添加编译器的地址在最后
1.subprocess.call()
虽然有个os的模块同样有os.system()函数来实现执行命令行的操作,但是似乎目前已经被subprocess取代了,同时subprocess 模块的使用灵活度比os大得多,所以在此只介绍使用subprocess模块的情况
如果是Linux系统请下载subprocess32,sudo pip install subprocess32
显然使用这个函数需要包含subprocess
的模块,括号中包含的字符串就是你平时在命令提示符窗口输入的指令,除了字符串似乎还支持list不过我不需要。如果是用codeblocks的话可以看到,在编译运行的时候,运行日志的前两行输出了命令行,代码示例:(注意其中的文件名均应该是绝对地址或相对地址)
import subprocess
subprocess.call("mingw32-gcc.exe -c test.c -o test.o")
subprocess.call("mingw32-g++.exe -o test.exe test.o")
Linux下的代码:(确保已经安装g++/gcc)
subprocess.call("g++ test.cpp -o test")
当然光是编译运行是不够的,我们要能执行C程序,还要提供输入与输出。如果是直接用subprocess.call("test.exe")
,系统默认的输入输出跟python程序的输入输出一样。我们也可以指定从文件输入输出就像是打ACM一样:文件的输入输出记得带上“r” 与“w”参数,否则会出错。
import subprocess
inp=open("in.txt","r")
out=open("res.txt","w")
subprocess.call("test.exe" , stdin=inp,stdout=out)
2.subprocess.Popen()
此处更新于 2019年8月10日,在重新尝试了上述内容后发现了部分需要增加的部分,所以记录在这里。
subprocess.call()函数虽然看起来非常好用但实际上却有着诸多的问题。官方文档告诉我们,在使用call()函数时如果指定了stdout stdin参数,则有可能会导致程序的死锁。同时如果要保证进程的安全,我们需要启用shell=True的参数。如果你是在linux环境下使用subprocess.call(),强烈建议启用shell=True,否则很多需要root权限的操作不能执行,会报错或者死锁。
而出于对call()函数的替代,我们可以使用它的父函数Popen()来完成操作。
Popen()函数同样存在stdin stdout stderr 与 shell等参数。最前面的一个字符串也是当作命令行来操作的。然而Popen()由于开启了新的进程,所以同多线程程序一样,python主程序是不会等待程序的完成的。通常情况下使用wait()函数可以使得主程序等待子进程的完成,但由于wait()是接收到子进程的return值后终结的,故当你指定了stdout 或stderr时可能会产生死锁现象。为了避免死锁建议使用communicate()函数。并且communicate()函数可以给子进程提供输出。使用示例:
child=subprocess.Popen("test.exe",stdout=out)
child.communicate(inp.read())
如果要考虑对子程序的更高级的使用,可以考虑使用terminate() 与kill()函数等,进行配合使用。具体参见官方文档