5

最近我开始学习管道以获得乐趣。我已经卡在了几个部分上,但我认为大部分都已经弄清楚了,但是我无法弄清楚如何获取输入以同时转发到程序并从该程序输出。

目前我有这个处理管道的 Perl 脚本:

#!/usr/bin/perl
use strict;
use warnings;
use threads;
use FileHandle;
use IPC::Open2;

my $cv_program = "./test"; #test is the compiled C program below
my $cv_message = "";
my $cv_currentkey = "";
my $pid = open2(*PIN, *POUT, $cv_program);
my $thread_pipeout = threads->create('PIPEOUT', \&PIN);

$thread_pipeout->detach();

while($cv_currentkey ne "\n")
{
    $cv_currentkey = getc(STDIN);
    $cv_message .= $cv_currentkey;
}
print POUT $cv_message;

sub PIPEOUT
{
    my $PIN = shift;
    while(<PIN>)
    {
        print $_;
    }
}

然后我有这个 C 程序,它只输出一些东西,要求一个字符串,然后打印那个字符串:

#include <stdio.h>

int main(int argc, char const *argv[])
{
    char input[100] = {0};

    printf("This is a test.\n");
    fgets(input, 100, stdin);
    printf("You entered %s\n", input);
    return 0;
}

运行 Perl 脚本的输出是:

~/Programming/Perl Pipes$ ./pipe.pl
Hello
This is a test.
You entered Hello

注意它在接受输入时会阻塞,然后在一个块中打印所有内容。我需要它来打印这是一个测试,然后像实际程序一样等待输入。

我还要注意的是我在 Perl 脚本中使用 getc 而不是 STDIN 的原因是因为我找不到让 STDIN 不阻塞 test.c 输出的方法,但是 getc 在时刻。

4

1 回答 1

7

我认为问题主要出在 C 端而不是 Perl 端。C 看到它的标准输出将进入管道,因此在查询标准输入之前确保它刷新其标准输出缓冲区并不是很严格。

要解决此问题,您应该可以添加以下行:

fflush(stdout);

在第一个之后printf和之前fgets

(免责声明:未经测试。)

于 2012-11-06T20:47:30.803 回答