2011-06-21 84 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); 
... 
相关问题