【问题标题】:Redirect stdin to stdout将标准输入重定向到标准输出
【发布时间】:2020-07-26 03:50:11
【问题描述】:

假设我有一个简单的 C 程序,它将 2 个数字加在一起:

#include <stdio.h>

int main(void) {
    int a, b;
    printf("Enter a: "); scanf("%d", &a);
    printf("Enter b: "); scanf("%d", &b);

    printf("a + b = %d\n", a + b);
    return 0;
}

我没有在每次执行时都输入终端,而是将ab 的值输入到一个文件中:

// input.txt
10
20

然后我将stdin 重定向到这个文件:

./a.out < input.txt

程序可以运行,但它的输出有点混乱:

Enter a: Enter b: a + b = 30

有没有办法将标准输入重定向到标准输出,这样输出就好像用户手动输入了值一样,即:

Enter a: 10
Enter b: 20
a + b = 30

【问题讨论】:

  • 没有可移植的方法,但是在 POSIX 系统上,您可以检查 isatty(0)(来自 unistd.h),如果 stdin 不是 tty,则在阅读后回显一行。
  • 有没有办法在不接触代码的情况下做到这一点?
  • 不修改代码不行。
  • 是的,有很多方法,但所有方法都需要更多代码:D 例如,在 Linux 上,您可以使用包装程序,使用 ptrace 调试程序并拦截所有 read 系统调用。 ..现在,也许修改源代码会更容易...
  • 真正的问题是input.txt 的输出必须出现在确切的位置,在Enter a: 之后必须有一个10。因为您可以tee /dev/stderr &lt;input.txt | a.out,但随后1020 将与您的程序输出不同步。因此,唯一的方法是将输入与程序的输出同步——这表明你必须跟踪程序的内部状态——或者通过跟踪程序中的read 系统调用,或者编写另一个程序来捕获像expect 这样的输出并采取相应的行动。

标签: c stdout stdin


【解决方案1】:

您可以为此使用期望。 Expect 是一个自动化交互式命令行程序的工具。以下是您可以自动输入这些值的方法:

#!/usr/bin/expect
set timeout 20

spawn "./a.out"

expect "Enter a: " { send "10\r" }
expect "Enter b: " { send "20\r" }

interact

这会产生如下输出:

$ ./expect     
spawn ./test
Enter a: 10
Enter b: 20
a + b = 30

还有更多例子here

【讨论】:

    【解决方案2】:

    忘记提示;试试这个:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main(void) {
        int a, b;
        if (scanf("%d%d", &a, &b) != 2) exit(EXIT_FAILURE);
        printf("%d + %d = %d\n", a, b, a + b);
        return 0;
    }
    

    您可能想找到一种方法让您的用户知道可执行文件的内容,或许可以添加命令行选项?

    $ echo "10 20" |./a.out 10 + 20 = 30 $ ./a.out --help 程序读取两个整数并显示它们的和 $

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多