2011-06-21 82 views
5

我看了這個題目,但他的問題可能不同於礦山 Writing to both stdout & a file如何都打印到標準輸出和文件用C

我想編寫一個函數,該函數需要打印到標準輸出和文件。我的C程序通過scanf獲取用戶輸入。

我打算寫如printf函數,但我真的不知道如何:

我嘗試這樣做,但它只能用「純」字符串的工作,不能轉換%d,%*。 LF(我的打印功能只需要兩個轉換)

void dupPrint(FILE *fp,char *string) 
{ 
    printf("%s",string); 
    fprintf(fp,"%s",string); 

    return; 
} 

我試圖DUP2和freopen函數,但他們並沒有爲我工作。

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

int main() 
{ 
    int i; 
    int file = open("input3.txt", O_APPEND | O_WRONLY); 
    if(file < 0) return 1; 

    if(dup2(file,1) < 0) return 1; 

    printf("Redirect to file!\n"); 
    printf("enter i : "); 
    scanf("%d",&i); 



    return 0; 
} 

這個dup2()教程只打印到文件。

我也試過發球,但可能是它無法工作,因爲我必須從用戶那裏獲取輸入(如果工作,它不是「公平」,因爲發球是不是在我的計劃)。

我想實現一個類似printf會解決問題,但我不知道如何轉換。* LF (打印出雙與用戶輸入精度)

#include <stdio.h> 
#include <stdarg.h> 
void dupPrint(FILE *fp,char *fmt, ...) 
{ 
    va_list ap; 
    char *p, *sval; 
    int ival; 
    double dval; 

    va_start (ap, fmt); //make ap point to 1st unnamed arg 
    for(p = fmt; *p; p++) 
     { 
      if (*p != '%') { 
       putchar(*p); 
       continue; 
      } 
      switch (*++p) { 
       case 'd': 
        ival = va_arg(ap, int); 
        printf("%d", ival); 
        break; 
       case '.*lf' //????? 
      } 
     }  

} 

任何人都可以提出一個解決方案我的問題?

+0

fprintf中可以打印到標準輸出,以及將文件 –

+1

您_could_打開調用'tee'和打印數據文件句柄的管道,但是這可能不夠可靠(如果這需要在沒有「tee」的系統上運行)。 –

+0

「我的C程序的scanf函數獲取用戶輸入」 - 你在痛苦的_world_是:-) – paxdiablo

回答

14

幸運的是,你不需要。你只需要使用的printffprintfv變體採取va_list,而不是直接的傳遞參數:

void tee(FILE *f, char const *fmt, ...) { 
    va_list ap; 
    va_start(ap, fmt); 
    vprintf(fmt, ap); 
    va_end(ap); 
    va_start(ap, fmt); 
    vfprintf(f, fmt, ap); 
    va_end(ap); 
} 
+2

+1使用名稱'tee'(這是當然的,對於這樣的功能,正確的名稱)。 –

2

使用可變參數函數和vprintf

void dupPrint(FILE *fp,char *fmt, ...) 
{ 
    va_list ap; 

    va_start(ap, fmt); 
    vprintf(fmt, ap); 
    va_end(ap); 

    va_start(ap, fmt); 
    vfprintf(fp, fmt, ap); 
    va_end(ap); 
} 

可選,實現vdupPrint,有dupPrint呼叫vdupPrint,並使用va_copy(如果C99可用)來複制va_list而不是我用的停止和重新起動方法。 (如果va_copy不提供給你,你就必須啓動兩個單獨的va_list S和他們都傳遞給vdupPrint,這是一個次優的解決方案,但會爲C89安全工作。)

2
在中間層

#define DUPPRINT(fp, fmt...) do {printf(fmt);fprintf(fp,fmt);} while(0) 
在您的應用程序代碼

... 
DUPPRINT(fd, "%s:%d\n", val_name, val_v); 
... 
相關問題