0

我有两个程序。第一个 ( subprocess.cpp) 用 C++ 编写:

#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;
}

该程序只是从标准输入中获取两个字符串并在标准输出上打印,毕竟是冲洗。test.py这是用 Python 2.7 编写的第二个程序 ( ):

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无法发送第二个字符串,因为它正在等待 '\n' 字符。

如果我将第二个更改scanfsubprocess.cpp( scanf("%s\n", line);no \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 的刷新刷新所有字符?

4

2 回答 2

2

错误是带有 \ni 格式字符串的 scanf 行为。它接缝 scanf("%s\n") 将在使用管道时在 \n 之后的第一个非空白字符之后或在使用终端时在第一个非空行之后返回(因为第一个非空白字符将在下一个 \n 之后被刷新)。

关键是您可能不是有意使用 scanf("%s\n")。我的猜测是你真正想要的是:

scanf("%s%*[^\n]", line);

它将读取单词,然后丢弃同一行中的所有字符。

于 2013-05-12T14:16:56.117 回答
1

问题在于scanf("%s\n", line),第二个scanf()需要读取另一行才能找到非空白字符。

对于类似的情况,这里有一个很好的解释。

我还检查了它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, 
于 2013-05-12T14:33:57.250 回答