2011-06-21 18 views
5

leí este tema, pero su problema puede ser diferente de la mía Writing to both stdout & a filecómo imprimir tanto en la salida estándar y el archivo en C

Quiero escribir una función, esa función es necesario imprimir a la vez la salida estándar y un archivo . Mi programa C recibe la entrada del usuario mediante scanf.

tengo la intención de escribir una función como printf pero no se sabe muy bien cómo:

yo probamos este, pero sólo puede trabajar con una cuerda "puro", no se puede convertir% d,% *. Si (mi función de impresión sólo se necesitan dos conversiones)

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

    return; 
} 

probé dup2 y freopen pero no funcionó para mí.

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

Este tutorial de dup2() solo imprime en el archivo.

También probé T, pero puede que no funcione porque tengo que obtener la opinión del usuario (si funciona, no es "justo" porque la T no está en mi programa).

pienso poner en práctica una voluntad resuelto el problema printf similar pero no saben cómo convertir. * Si (imprimir doble con facilidad de entrar en la precisión)

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

} 

¿Puede alguien sugerir una solución para ¿mi problema?

+0

fprintf puede imprimir a la salida estándar, así como a los archivos –

+1

Usted _could_ abrir una tubería que llama 'tee' e imprimir datos a ese gestor de archivo, pero esto puede no ser lo suficientemente confiable (si esto necesita ejecutarse en sistemas sin 'tee'). –

+0

"El programa My C recibe la entrada del usuario mediante scanf" - se encuentra con un _world_ of pain :-) – paxdiablo

Respuesta

14

Afortunadamente, no es necesario. Lo que desea es utilizar las variantes de vprintf y fprintf que tomar una va_list en lugar de sus argumentos pasando directamente:

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 por usar el nombre 'tee' (que es, por supuesto, el nombre propio de tal función). –

2

¡Utilice una función variable y 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); 
} 

Opcionalmente, implementar vdupPrint, tienen dupPrint llamada vdupPrint, y el uso va_copy (si está disponible C99) para duplicar la va_list en lugar del método de parada y reinicio he usado. (Si va_copy no está disponible para usted, usted tiene que comenzar dos separados va_list s y pasarlos tanto a vdupPrint, que es una solución sub-óptima, pero trabajará para el C89 con seguridad.)

2

en la capa intermedia :

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

en el código de aplicación:

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