How to print on both stdout and file in C

I read this topic, but its problem may be different from mine. Writing to stdout and file

I want to write a function, this function needs to be printed for both stdout and the file. My C program receives user input scanf.

I intend to write a function like printf, but I really don't know how:

I tried this, but it can only work with a "clean" string, cannot convert% d,%. * lf (my print function needs only two conversions)

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

    return;
}

I tried dup2 and freopen, but they did not work for me.

#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;
}

This tutorial dup2 () only prints to a file.

I also tried tee, but maybe it doesn’t work because I have to get input from the user (if it works, this is not “fair” because tee is not in my program).

, 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' //?????
           }
       }       

}

- ?

+5
4

, . v printf fprintf, 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);
}
+14
+3

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);
}

Optionally, we implement vdupPrint, have a dupPrintcall, vdupPrintand use va_copy(if C99 is available) to duplicate va_listinstead of the stop and restart method used. (If it’s va_copynot available to you, you need to run two separate ones va_listand pass them both on vdupPrint, which is a suboptimal solution, but will work safely on C89.)

+2
source

in the middle layer:

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

in your application code:

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

All Articles