2016-01-23 124 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

相關問題