Как распечатать как на стандартный вывод и файл в C - PullRequest
5 голосов
/ 21 июня 2011

Я читаю эту тему, но его проблема может отличаться от моей Запись в stdout и в файл

Я хочу написать функцию, которую нужно распечатать на оба 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, но может быть, это не сработает, потому что я должен получить информацию от пользователя (если работа, это не "честно", потому чтов моей программе нет).

Я думаю, что реализация 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 ]

14 голосов
/ 21 июня 2011

К счастью, вам не нужно.Вы просто хотите использовать 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);
}
3 голосов
/ 21 июня 2011

Вы можете реализовать свою функцию dupPrint, используя vfprintf и va_list / va_start / va_end .

2 голосов
/ 21 июня 2011

в среднем слое:

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

в вашем коде приложения:

...
DUPPRINT(fd, "%s:%d\n", val_name, val_v);
...
2 голосов
/ 21 июня 2011

Используйте функцию variadic и 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.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...