2016-01-23 140 views
-1

如果我使用printf ("Hello!");有什么方法可以读取我输入到stdout的内容吗?是否可以从stdout读取?

我看到C language. Read from stdout(它使用管),但它不工作:

#define _XOPEN_SOURCE 

#include <stdio.h> 
#include <unistd.h> 

#define DIM 10 

int main(void) 
{ 
    char s[DIM]; 
    int fds[2]; 

    pipe(fds); 
    dup2(fds[1], fileno(stdout)); //I added fileno() 

    printf("Hello world!"); 

    read(fds[0], s, DIM); 
    printf("\n%s",s); 

    return 0; 
} 

我也使用文件描述符尝试,但没有它不工作:

#define _XOPEN_SOURCE 

#include <stdio.h> 
#include <unistd.h> 

#define DIM 10 
#define MYFILE "/path/file" 

int main(void) 
{ 
    FILE *fd; 
    char s[DIM]; 

    fd = fopen(MYFILE,"w+"); 
    dup2(STDOUT_FILENO, fileno(fd)); 

    printf("Hello world!"); 

    fseek(fd, 0, SEEK_SET); 
    fgets(s, DIM, fd); 

    printf("\n%s",s); 
    return 0; 
} 

哪有我做?

+0

时,在第一个代码,重定向是活动的,所以任何*打印*会去管,你什么也看不见。在示例2中,重定向是反向进行的(将参数更改为dup2调用)。无论如何,从stdout读取是一个无意义的,标准输出是一个out stream;并且读取您写入stdout的内容不能通过单个进程以此方式进行。但更一般地说,你想要的是*奇怪*,你为什么要这样? –

回答

1

一般不会,除非标准输出已被重定向到文件。写入标准输出(例如printf())的函数不会将它们的输出记录到进程中的任何位置,也无法从除正常文件以外的任何其他位置读取以前的输出。例如,如果您的进程将其输出打印到终端,则尝试从终端读取数据将返回用户输入的内容,而不是您以前输出的内容。

你的第二个程序是差不多工作。还有,你需要首先解决,但也有一些小问题:

  1. 从第一printf()不会输出的输出,因为它缺少一个换行符。要么添加一个换行符,要么呼叫fflush(stdout)强制它被输出。

  2. 您正在尝试printf()您的结果,但标准输出仍然指向该文件,因此您永远不会看到它。在覆盖标准输出后显示内容的最简单方法是使用fprintf(stderr, ...)

(*:或者表现得非常像文件一样,块设备或命名管道的某些事情,但你可能不与那些工作)

+0

如果我使用终端,我只能获得输入吗?不输出? – sbam

+0

@SimoneBonato正确。写入终端会生成输出;从终端读取给你输入。 – duskwuff

+0

我指的是“写入标准输出的函数(如printf())不会将它们的输出记录到您的进程中的任何位置”。在终端,也有我以前的输出... – sbam

1

如果stdout是一个文件,你可以打开另一个文件描述符并寻找和读取。另一方面,如果它是管道,则不能。写入管道的数据只能读取一次。如果该管道的读端与tty关联,则它将被设备驱动程序读取,并且不再可供您的进程读取。 dup文件描述符不会使数据可用两次,因此使用dup2的方法无法工作(实际上,dup2(fds[1], STDOUT_FILENO)首先关闭了STDOUT_FILENO,因此现在您只需写入管道)。你可以派生一个复制数据的进程,或者使用splice/tee系统调用来复制数据,但是你真的需要问:你为什么要这样做?

+0

好的,但在我的示例输出中,尽管有'dup2',仍然在stdout中继续输出。 – sbam

相关问题