25

私のプログラムは、ログと stdout に書き込みます。ただし、すべてのメッセージには特定の優先度があり、ユーザーはプリファレンスでどの優先度がどのストリーム (ログまたは標準出力) に送られるかを指定します。

unsigned short PRIO_HIGH = 0x0001;
unsigned short PRIO_NORMAL = 0x0002;
unsigned short PRIO_LOW = 0x0004;

設定は、いくつかのフラグによって処理されます。

unsigned short PRIO_LOG = (PRIO_HIGH | PRIO_NORMAL);
unsigned short PRIO_STD = (PRIO_HIGH);

このwrite_log関数は、printf 関数と同じパラメーターで動作する必要がありますが、パラメーターが追加されていますunsigned short priority

write_log((PRIO_NORMAL|PRIO_LOW), "HELLO %s, take %d", "World", 1);

(PRIO_NORMAL|PRIO_LOW意味不明ですが…)

フラグのチェックは簡単です: if(priority & PRIO_LOG)(両方の引数にフラグが設定されている場合は >1 を返します)

ただし、文字列リテラルとフォーマット引数を printf 関数に渡す方法がわかりません。誰か助けてくれたり、ポインタをくれたりできますか (同じ効果を達成する別の方法が可能です)? それは大歓迎です。

4

3 に答える 3

59

C の可変引数 " varargs " 機能を使用して、printf() の代わりに vprintf() を呼び出したいとします。

#include <stdarg.h>

int write_log(int priority, const char *format, ...)
{
    va_list args;
    va_start(args, format);

    if(priority & PRIO_LOG)
            vprintf(format, args);

    va_end(args);
}

詳細については、この行に沿った何かを参照してください。

于 2009-10-04T13:15:50.487 に答える
9

私はジェフのアイデアが進むべき道だと思いますが、vprintf を使わずにマクロでこれを達成することもできます。これには gcc が必要になる場合があります。

#define write_log(priority,format,args...)        \
                  if (priority & PRIO_LOG) {      \ 
                      printf(format, ## args);    \
                  }

これがどのように機能するかについては、こちらをご覧ください。

于 2009-10-04T18:42:15.990 に答える
4

PRIO_ *定義をビットとして使用する場合(|および&を使用)、それぞれに独自のビットを指定する必要があります。

unsigned short PRIO_HIGH = 0x0001;
unsigned short PRIO_NORMAL = 0x0002;
unsigned short PRIO_LOW = 0x0004;

マクロは、do {} while(0)表記を使用して改善できます。これにより、write_logの呼び出しがステートメントのように機能します。

#define write_log(priority,format,args...) do { \
    if (priority & PRIO_LOG) { \
        printf(format, ## args); \
    } while(0)
于 2009-10-05T15:45:16.463 に答える