2011-12-20 4 views
1

У меня есть макрос как такойPrintf в макрос в C

#define PTF(A,y) fprintf(file,"%s",A,y);printf("%s %d",A,y); 

так, что он будет печатать в файл и консоли так, например, я называю эту функцию Макро

int y=9; 
PTF("\nRound %d \n",y); 

таким образом, я нужно у = 9 будет показано, как часть аргумента а так мой fprintf в файле будет выглядеть ниже

Round 9 

потому что у меня много изменений, чтобы сделать, если бы я, чтобы изменить это, следовательно, в надежде на легкий выход =)

+1

Итак ... В чем вопрос? – tangrs

+0

в функции fprintf, он будет печатать как «Round% d». так что мне интересно, есть ли способ распознать y, который будет показан в fprintf. – edelweiss

+0

Это касается вашего вопроса, но подумайте о том, что произойдет, если кто-то будет называть ваш макрос следующим образом: 'if (cond) PTF («% d», y); ', где' cond' - некоторое условие (неважно, что это такое). – NPE

ответ

1

Изменение

#define PTF(A,y) fprintf(file,"%s",A,y);printf("%s %d",A,y);

в

#define PTF(A,y) fprintf(file,A,y);printf("%s %d",A,y);

Примечание :

PTF("Round %d",9); будет иметь отпечаток Round 9 к файлу но printf покажет Round %d 9.

Вы также должны убедиться, что вы указываете только один спецификатор для fprintf

+0

СПАСИБО! он работал так, как я хотел! =) – edelweiss

0

Если вы» re используя Unix (BSD/Linux/Solaris/etc.), возможно, проще использовать tee для этого.

+0

Что делать, если 'файл' должен меняться во время выполнения программы? Я не вижу «тройника» в качестве решения. Вопрос заключается в том, как писать макросы, а не о том, как разделить вывод. –

+0

Я сказал «может быть». Много случаев, когда мы жестко кодируем, вместо того, чтобы использовать что-то уже существующее. – ern0

4

Макросы - это неправильный способ сделать это; особенно в этой конструкции, вы столкнетесь с каждой малой ловушкой. Представьте себе:

if(condition) 
    PTF("%s", foo); 

Просто написать VARIADIC функции:

void 
ptf(char *fmt, ...) 
{ 
    va_list ap; 
    va_start(ap, fmt); 
    vprintf(fmt, ap); 
    va_end(ap); 
    va_start(ap, fmt); 
    vfprintf(file, fmt, ap); 
    va_end(ap); 
} 
0

Распространенное идиома использовать do { ... } while (0) (некоторые компиляторы будут выдавать предупреждение для этого), или оператора запятой , и приложить свои заявления в круглых скобках (но вы не можете использовать и управлять оператором потока).

Если вы можете положиться на наличие современного компилятора (например, GCC 3+), вы можете использовать переменные макросы для определения макроса так, чтобы он был похож на обычный printf.

Я хотел бы пойти на что-то вроде:

#define PTF(...) (fprintf(file,__VA_ARGS__),printf(__VA_ARGS__)) 

так что PTF("Round %d",y) напечатает Round 9 (предполагая, что у = 9) и на file и stdout.

Обычное предостережение о побочных эффектах в макросах применяется: никогда, никогда не используйте PTF("%d",y++).