【问题标题】:C redirect stdin to keyboardC 将标准输入重定向到键盘
【发布时间】:2014-07-21 14:54:32
【问题描述】:

我在 Mac OSX 上编写了一个小型 C 程序,它执行以下步骤:

  1. 从标准输入读取一些输入并将输入存储到内存中。
  2. 运行一些计算并将输出打印到 stdio

在第 1 步和第 2 步之间,我想提示用户并等待某种键盘输入来表示“继续执行第 2 步”。问题是使用命令调用程序时stdin已被重定向:

$ ./simple < input.in

我想在读取文件后将标准输入重定向到键盘,但不知道该怎么做。我尝试过使用

fclose(stdin);
freopen("newin", "r", stdin);

但此后标准输入无法从键盘读取。任何有关如何执行此操作的建议将不胜感激。

还有几点:

  • 真正的程序比这更复杂,但简单仍然可以说明我的问题。
  • 这样做的原因是我想在执行过程中暂停我的程序,以便我有足够的时间将“简单”进程加载到名为 Instruments 的 OSX 应用程序中以进行性能分析。
  • 如果有帮助,下面提供了更多示例代码。

int main(void) {

    // STEP 1
    int array[ARRLEN];
    readinput(array, ARRLEN);


    // WAIT FOR KEYBOARD INPUT TO PROCEDE
    // redefine stdin to keyboard
    fclose(stdin);
    freopen("newin", "r", stdin);
    char c[5]; 
    char cmp[5] = ".";
    puts ("Enter text. Include a dot ('.') in a sentence to exit:");

    while (1) {
        fgets(c, sizeof(c), stdin);
        printf("c = %s\n", c);
        // if (strcmp(c, cmp))
        //     break;
        sleep(1);
    }

    // STEP 2
    // do something here
    return 0;
}

【问题讨论】:

  • 如果你需要从文件中读取,为什么你重定向标准输入,当你可以用fopen()打开文件并从中读取?
  • 为了程序,我可以这样做,但它是用于 Uni 分配,他们运行/测试程序的方法将使用标准输入管道
  • 如果他们运行某种自动测试,你最好不要尝试阅读键盘。不会有人在上面打字。如果您的作业需要阅读stdin,请阅读stdin

标签: c stdin instruments


【解决方案1】:

除非您想要使用名为newin 的文件,否则您的freopen 调用将失败。 (此外,在调用freopen 之前不能关闭流,因为freopen 需要一个有效的流,它会作为副作用关闭。)要重新打开标准输入以从终端读取,您需要指定/dev/tty作为文件名:

if (!freopen("/dev/tty", "r", stdin)) {
    perror("/dev/tty");
    exit(1);
}

如果程序在您的控制之下,则没有理由重新打开 stdin 开始 - 只需将 /dev/tty 作为单独的文件指针打开,并使用它来获取交互式输入:

FILE *tty = fopen("/dev/tty", "r");
if (!tty) {
    perror("/dev/tty");
    exit(1);
}
...
while (1) {
    fgets(c, sizeof(c), tty);
...
}

在任何一种情况下,都无法使用 shell 管道自动执行交互式响应,但这似乎是您想要的。从/dev/tty 读取是支持输入重定向和交互工作的命令行程序的标准做法,例如一些 Unix 编辑器。

【讨论】:

  • 就像一个魅力!非常感谢,对了解也很有用
  • 我发现如果我进入 proccess 的 /proc/PID/fd 文件夹,'0' 链接指向的是在命令行中被重定向的文件——这就是为什么键盘输入没有不行。那么,你知道我可以在哪里阅读更多关于这个重定向过程(它的内部工作)的信息吗?如果我可以将其反转为指向 /dev/pts/n 而不是打开另一个文件描述符。哦,你的回答帮助了我很多
  • @EnzoFerber 我猜你可以使用dup() 来让文件描述符0 指向TTY。但我不明白你的情况的细节;您可能需要考虑提出一个单独的问题,详细说明该问题以及您解决该问题的尝试。
猜你喜欢
  • 1970-01-01
  • 2016-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多