0

私は、かなり一般的なマクロであると想像するものを書きたいと思っています。次の形式のマクロの束を定義することにより、多くのPOSIXプログラムで繰り返される「-v」オプションをエミュレートしたいと思います。

#define V1(str, ...) if(optv >= 1){printf("%s: "str,prog,__VA_ARGS__);}

int main(int argc, char* argv[])
{
  // ... stuff ...
  int i = 1;
  V1("This contains a variable: %d\n",i);
}

// Output:
// ./program: This contains a variable: 1

ここoptvで、コマンドラインで見つかった「-v」オプションの数をカウントしprog、プログラム名を含みます(どちらも表示されていません)。これはうまく機能しますが、問題は変数を使用する必要があることですV1("Output")コンパイラエラーが発生します。私はいつでも使うことができV1("Output%s","")ましたが、よりクリーンな解決策があるはずです。

4

4 に答える 4

5

GNU Cプリプロセッサには、トークン貼り付け演算子を次のように付加することにより、可変個引数部分を埋める引数がない場合に末尾のコンマを削除できる特別な機能があります。##__VA_ARGS__

#define V1(str, ...) if(optv < 1); else printf("%s: "str,prog, ## __VA_ARGS__)

または、C99に完全に準拠したままにする場合は、フォーマット文字列パラメーターを省略記号に組み込むことができますが、この場合prog、フォーマット文字列とvarargs。このようなものが機能する可能性があります:

#define V1(...) if(optv < 1); else myprintf(prog, __VA_ARGS__)
int myprintf(const char *prog, const char *fmt, ...)
{
    // Print out the program name, then forward the rest onto printf
    printf("%s: ", prog);

    va_list ap;
    va_start(ap, fmt);
    int ret = vprintf(fmt, ap);
    va_end(ap);

    return ret;
}

次に、C99以外のコンパイラ拡張機能を使用せずににV1("Output")展開します。myprintf(prog, "Output")

編集

また、中かっこなしでステートメントif内でマクロを呼び出すと発生する可能性のある奇妙な問題のために、マクロの条件を逆にしたことに注意してください。詳細な説明については、このFAQを参照してください。if

于 2012-02-24T23:13:07.860 に答える
1

詳細レベルごとに2つの異なるマクロを使用してみませんか。メッセージと変数を出力するものと、メッセージを出力するだけのものですか?

于 2012-02-24T22:59:07.773 に答える
1

あなたがきれいに仕事をすることができるようにあなたはおそらくあなた自身に小さなサポート関数を書くべきです:

extern void vb_print(const char *format, ...);

#define V1(...)  do { if (optv >= 1) vb_print(__VA_ARGS__); } while (0)

optvとは両方ともprogグローバル変数だと思います。これらはヘッダーに入ります(プログラム自体に書き出すことはありませんよね?)。

関数は次のようになります。

#include <stdio.h>
#include <stdarg.h>

extern const char *prog;

void vb_print(const char *format, ...)
{
    va_list args;
    va_start(args, format);
    printf("%s:", prog);
    vprintf(format, args);
    va_end(args);
}

そこにはロケット科学はありません。システムを心ゆくまで微調整して、情報の書き込み場所の選択、出力のフラッシュ、最後に改行があることの確認などを行うことができます。

于 2012-02-24T23:17:41.603 に答える
0

これを試して:

#define V1X(str, ...) if(optv >= 1) {printf("%s: "str,prog,__VA_ARGS__);} else
#define V1(...) V1X(__VA_ARGS__,0)

これであなたが説明した問題は修正さelseれ、最後に別の問題が修正されたと思います。

于 2012-02-24T23:06:40.140 に答える