2016-06-11 99 views
1

我想將stdout和stderr重定向到一個函數並編寫一個簡單的代碼。 fprintf是好的,但是當我使用printf沒有\ r,流傳遞給終端!重定向stdout/stderr在C中運行

#include <stdio.h> 
static ssize_t file_write(void *c, const char *buf, size_t size) 
{ 
    FILE * pFile; 
    pFile = fopen ("output.txt","w"); 
    fprintf(pFile, "%s", buf); 
    fclose (pFile); 

return size; 
} 

void redirect() 
{ 
    FILE *stream; 
    stream=fopencookie(NULL, "w", (cookie_io_functions_t) {(ssize_t) 0, file_write, 0, 0}); 
    setbuf(stdout, NULL); 
    stdout = stream; 
    setbuf(stderr, NULL); 
    stderr = stream; 
} 

int main() 
{ 
    redirect(); 
    fprintf(stderr,"1-stderr test\n"); 
    fprintf(stdout, "2-stdout test\n"); 
    printf("3-printf with r test\n\r"); 
    printf("4-printf without r test\n"); 

return 0; 
} 

文件 「output.txt的」:

1- stderr的測試
2-標準輸出測試
3- printf的隨r測試

端子輸出:

$ ./sample
4-printf without r test

+1

1.排除縮進2.爲什麼不檢查'fopen'的返回值3.'fprintf(pFile,buf);' - 讓我們希望'buf'中不包含'%'! –

+1

您正在使用'buf'作爲格式字符串。如果它包含任何'%'字符,這將失敗得相當可怕。使用'fprintf(pFile,「%s」,buf)'或者調用'fwrite'而不是'fprintf'。 –

+0

你也可以調用'fputs'而不是'fprintf'。這可能是最簡單的。 –

回答

1

您不能將標準輸入或標準輸出重定向到程序中的函數。

然而,您可以創建一對管道並用這些管道替換標準輸入和輸出,並且有另一個功能(可能在另一個線程或子進程中)使用管道的另一端與該函數進行通信。

你當然可以使用例如setvbufstdinstdout的緩衝區更改爲您提供的一對緩衝區,然後您可以像任何其他內存緩衝區(即陣列)一樣直接從緩衝區讀取數據,或直接寫入緩衝區。不是我推薦它,但它很脆弱,容易出錯。

但是,在這種情況下,似乎你想要的是所有寫入stdout的文件都應該轉到該文件。在這種情況下(如使用管道),沒有標準的C處理方式,但需要使用特定於操作系統的功能。然後,如果您在POSIX平臺(如Linux或OSX)上,則可以告訴操作系統複製文件的底層文件描述符,並說STDOUT_FILNO(這是用於stdout的文件描述符)是重複的您打開的文件的文件描述符。然後將所有寫入stdout的內容寫入您的文件。爲此,您需要使用the dup2 system call