我有以下 python 代码,它应该为 C++ 程序提供初始输入,然后获取其输出并将其反馈给它,直到程序完成执行:
通讯.py
p = subprocess.Popen('test__1.exe', bufsize=1, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=False)
p.stdin.flush()
p.stdout.flush()
x = b'1\n'
while True:
p.stdin.write(x)
p.stdin.flush()
p.stdout.flush()
x = p.stdout.readline()
print(x)
if p.poll() != None:
break
我目前正在使用两个简单的 C++ 程序对其进行测试:
测试__1.cpp:
#include <iostream>
using namespace std;
int main()
{
for( int i = 0; i < 3; ++i )
{
int n;
cin >> n;
cout << n+1 << endl;
}
return 0;
}
测试__2.cpp
#include <cstdio>
int main()
{
for( int i = 0; i < 3; ++i )
{
int n;
scanf("%d", &n);
printf("%d\n", n+1);
}
return 0;
}
当 comm.py 打开 test__1.exe 时,一切正常,但是当它打开 test__2.exe 时,它在第一次调用时挂起readline()。 请注意,当我在执行前向 test__2.exe 提供整个输入(即最初设置 x = '1\n2\n3\n')时,不会发生此问题 p>
可能导致此问题的原因是什么?
(此外,comm.py 应该能够处理任何有效的 C++ 程序,因此仅使用 iostream 不是一个可接受的解决方案。)
编辑:我还需要在 Windows 上工作的解决方案。
最佳答案
这是由于 std::endl
刷新 ostream
而 printf
没有刷新 stdout
,
正如您通过修改 test__2.cpp
可以看到的,如下所示:
#include <cstdio>
int main()
{
for( int i = 0; i < 3; ++i )
{
int n;
scanf("%d", &n);
printf("%d\n", n+1);
fflush(stdout); //<-- add this
}
return 0;
}
你说你想要模块化以正确地与任何 C++ 程序一起工作,所以 你不能依赖它刷新标准输出(或标准错误) 每次写入后。
这意味着您必须使程序的标准流无缓冲
并在程序本身外部这样做。你需要这样做
在 comm.py
中。
在 Linux(或其他提供 GNU Core Utils 的主机)中,您可以通过
通过stdbuf
执行程序,例如
import subprocess
cmd = ['/usr/bin/stdbuf', '-i0','-o0', '-e0', './test__2']
p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=False)
p.stdin.flush()
p.stdout.flush()
x = b'1\n'
while True:
p.stdin.write(x)
x = p.stdout.readline()
print(x)
if p.poll() != None:
break
取消所有标准流的缓冲。对于 Windows,您将需要 研究如何做同样的事情。暂时不知道。
关于 python : communication with c++ command line program not working when using <cstdio>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41660740/