Скомпилируйте программу C/C++ и сохраните стандартный вывод в файле через Python

Допустим, у меня есть файл C/C++ с именем userfile.c.

Используя Python, как я могу вызвать локальный компилятор gcc, чтобы файл был скомпилирован и создан исполняемый файл? В частности, я хотел бы предоставить некоторый ввод (stdin) через некоторый файл input.txt, и я хочу сохранить стандартный вывод в другом файле с именем output.txt. Я видел некоторую документацию, которая мне понадобится для использования подпроцесса, но я не уверен, как это вызвать и как обеспечить пользовательский ввод.


person thematroids    schedule 20.10.2015    source источник
comment
Вы можете использовать SCons.   -  person Peter Wood    schedule 20.10.2015
comment
Как input.txt и output.txt связаны с программой в userfile.c? Нужно ли запускать исполняемый файл C после компиляции?   -  person Mathias Rav    schedule 20.10.2015
comment
@MathiasRav: Да, я хочу предоставить данные из input.txt как стандартный ввод для исполняемого файла.   -  person thematroids    schedule 20.10.2015


Ответы (2)


Простое решение будет таким, как показано ниже:

import subprocess

if subprocess.call(["gcc", "test.c"]) == 0:
    subprocess.call(["./a.out <input.txt >output.txt"], shell=True)
else: print "Compilation errors"

2 предостережения:

  1. Я жестко кодирую вещи. Вы можете захотеть параметризовать и все такое.
  2. Установка для shell значения True является угрозой безопасности, согласно документации Python.
person sam noir    schedule 20.10.2015
comment
Это не работает в Windows, но отлично работает в Mac OS X. Как мне заставить его работать в Windows? - person thematroids; 23.01.2016

Вот возможное решение (написано для Python 3):

import subprocess

subprocess.check_call(
    ('gcc', '-O', 'a.out', 'userfile.c'),
    stdin=subprocess.DEVNULL)

with open('input.txt') as infile, open('output.txt', 'w') as outfile:
    subprocess.check_call(
        ('./a.out',),
        stdin=infile,
        stdout=outfile,
        universal_newlines=True)

Параметр universal_newlines заставляет subprocess использовать для ввода и вывода строки, а не байты. Если вам нужны байты, а не строки, откройте файлы в двоичном режиме и установите universal_newlines=False.

При ошибках компиляции или запуска в двух программах subprocess.CalledProcessError будет поднял subprocess.check_call.

person Mathias Rav    schedule 20.10.2015