我有两个程序。用C ++编写的第一个(subprocess.cpp
):
#include <stdio.h>
int main() {
char * line = new char[1000];
// first scan
scanf("%s\n", line);
printf("%s\n", line);
fflush(stdout);
// second scan
scanf("%s\n", line);
printf("%s\n", line);
fflush(stdout);
return 0;
}
这个程序只是从stdin获取两个字符串并在stdout上打印,毕竟是刷新。
这是用Python 2.7编写的第二个程序(test.py
):
from subprocess import Popen
from subprocess import PIPE
from subprocess import Popen
# create process
my_process = Popen("./subprocess", stdin = PIPE, stdout = PIPE)
# send initial data
my_process.stdin.write('abc\n')
my_process.stdin.flush()
my_process.stdin.write('xyz\n')
my_process.stdin.flush()
# read data from subprocess
print "Subprocess line 1 :: " + str(my_process.stdout.readline())
print "Subprocess line 2 :: " + str(my_process.stdout.readline())
此脚本应启动子进程,发送和检索两个字符串。看看开心的是什么:
marcin@marcin-Aspire-7540 ~/Desktop/inzynierka $ g++ subprocess.cpp -o subprocess
marcin@marcin-Aspire-7540 ~/Desktop/inzynierka $ python test.py
Subprocess line 1 :: abc
test.py
正在等待程序subprocess
的第二行。程序subprocess
无法发送第二个字符串,因为它正在等待&#39; \ n&#39;字符。
如果我将scanf
中的第二个subprocess.cpp
更改为scanf("%s\n", line);
(无\n
),一切正常。当我在test.py
中发送一行时,也会发生同样的情况:
# send initial data
my_process.stdin.write('abc\n')
my_process.stdin.flush()
my_process.stdin.write('xyz\n')
my_process.stdin.flush()
my_process.stdin.write('ADDITIONAL\n')
my_process.stdin.flush()
似乎Python在刷新后不发送最后的\ n字符(参见更改的scanf示例)。在test.py
中添加一个额外的写入和刷新证明,在刷新后,丢失的\ n字符仍然在缓冲区中。
该怎么办?如何使Python刷新所有字符?
答案 0 :(得分:2)
错误是使用\ n i格式字符串的scanf行为。它接缝是scanf(“%s \ n”)将在使用管道之后的第一个非空白字符后返回,或者在使用终端时在第一个非空行之后返回(因为第一个非空白字符将在下一个之后刷新\ n )。
关键是你可能并不想使用scanf(“%s \ n”)。我的猜测是你真正想要的是:
scanf("%s%*[^\n]", line);
将读取单词,然后丢弃同一行中的所有字符。
答案 1 :(得分:1)
问题在于scanf("%s\n", line)
,第二个scanf()
需要在找到非空白字符之前读取另一行。
类似案例here有一个很好的解释。
我还用strace
检查了它,Python发送了最后一个'\n'
字符。
pid 6611: test.py
pid 6613: subprocess
> strace -f python test.py
[pid 6611] write(4, "abc\n", 4 <unfinished ...>
...
[pid 6611] write(4, "abc\n", 4 <unfinished ...>
...
[pid 6613] read(0, "abc\nxyz\n", 4096) = 8
...
[pid 6613] write(1, "abc\n", 4) = 4
[pid 6611] <... read resumed> "a", 1) = 1
[pid 6613] read(0, <unfinished ...>
[pid 6611] read(5, "b", 1) = 1
[pid 6611] read(5, "c", 1) = 1
[pid 6611] read(5, "\n", 1) = 1
...
[pid 6611] write(1, "Subprocess line 1 :: abc\n", 25Subprocess line 1 :: abc) = 25
[pid 6611] write(1, "\n", 1) = 1
[pid 6611] read(5,