python stdout.flush()不会刷新像'\ n'这样的最后一个白色字符

时间:2013-05-12 13:28:56

标签: python stdout stdin flush

我有两个程序。用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刷新所有字符?

2 个答案:

答案 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,