如何在C中打印到stdout和文件

时间:2011-06-21 03:59:32

标签: c file-io

我读了这个主题,但他的问题可能与我的不同 Writing to both stdout & a file

我想写一个函数,该函数需要打印到stdout和一个文件。我的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()教程仅打印到文件。

我也试过tee,但可能不行,因为我必须得到用户的输入(如果工作,那不是“公平的”因为tee不在我的程序中)。

我认为实现类似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' //?????
           }
       }       

}

有人可以为我的问题提出解决方案吗?

4 个答案:

答案 0 :(得分:14)

幸运的是,你不需要。您只想使用vprintf的{​​{1}}变体,而fprintf代替直接传递的参数:

va_list

答案 1 :(得分:3)

您可以使用vfprintfva_list/ va_start / va_end来实施dupPrint功能。

答案 2 :(得分: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);
}

(可选)实施vdupPrintdupPrint致电vdupPrint,然后使用va_copy(如果C99可用)复制va_list而不是停止我使用的重启方法。 (如果您无法使用va_copy,则必须启动两个单独的va_list并将它们传递给vdupPrint,这是次优解决方案,但适用于C89安全。)

答案 3 :(得分:2)

在中间层:

#define DUPPRINT(fp, fmt...) do {printf(fmt);fprintf(fp,fmt);} while(0)

在您的应用代码中:

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