C将stdin重定向到键盘

时间:2014-06-01 09:29:04

标签: c stdin instruments

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

  1. 从stdin读取一些输入并将输入存储到内存中。
  2. 运行一些计算并将输出打印到stdio
  3. 在步骤1和2之间,我想提示用户并等待某种键盘输入以发出“继续进行到步骤2”的信号。问题是当使用命令调用程序时,stdin已被重定向:

    $ ./simple < input.in
    

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

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

    但是此后stdin无法从键盘读取。任何关于如何做到这一点的建议将不胜感激。

    还有一些要点:

    • 真正的程序比这更复杂,但简单仍然说明了我的问题。
    • 原因是我想在执行期间暂停我的程序,以便我有足够的时间将“简单”过程加载到称为性能分析工具的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;
    }
    

1 个答案:

答案 0 :(得分:3)

除非您要使用名为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编辑器。