3

VS2010では、情報をファイルにダンプするために次の可変長マクロを作成しました。

#define INDENT(fp, indent) for(size_t __i = 0; __i < (indent); ++__i) fprintf((fp), "  ")
// IND_FP = indented fprintf.
// This macro uses two IMPLICIT parameters.
// 1. (FILE *)fp is a pointer to the output file.
// 2. (size_t)indent specifies the indentation level.
#define IND_FP(format, ...) do{ INDENT(fp, indent); fprintf(fp, format, __VA_ARGS__); }while(0)

これらのマクロは、私のプログラムで頻繁に発生します。

void CMAP::dump_info(FILE *fp, size_t indent){
  IND_FP("<cmap tableVersion=\"0x%08x\" numberOfEncodingTables=\"%d\">\n",
    table_version_number, num_encoding_tables);
  //...
  IND_FP("</cmap>\n");
}

悲しいことに、コードをアンティルビアン IDE のVC++6.0に移行する必要がありますが、これは可変個引数マクロをサポートしていません。代わりに可変個引数関数を書きました。

void IND_FP(FILE *fp, size_t indent, char *format, ...){
  INDENT(fp, indent);
  va_list arg_ptr;
  va_start(arg_ptr, format);
  vfprintf(fp, format, arg_ptr);
  va_end(arg_ptr);
}

しかし、数百行ではないにしても数十行のコードを から に変更する必要がありIND_FP(format, ...)ますIND_FP(fp, indent, format, ...)

私を助けることができるマクロのトリックはありますか? それとも、明示的な引数を使用して冗長性に慣れた方がよいでしょうか?

4

3 に答える 3

1
#define IND_FP Logger(indent)

class Logger {
  public:
    Logger(int indent);
    int operator()(FILE* fp, char* format, ...);
  private:
    // an exercise for the reader
};
于 2014-05-25T09:37:43.880 に答える
0

それらを使用しないことで、ラウンド変数を取得できます。FILE* の代わりに ofstream を使用します。このようなもの

#define LOGGER(logfile,loginfo)  logfile << loginfo << std::endl

logfile というオブストリームを宣言したとします。単純なものには、使用できます

LOGGER(logfile, x);

より複雑にしたい場合は、次を使用できます

LOGGER(logfile, "x = " << x << "  b=" << b);

インデントには、グローバルを使用できます

// declaration
char spaces[128];
...
// Initialization
memset(spaces, ' ', sizeof(spaces));

#define LOGGER(logfile,indent,loginfo) \
    spaces[indent] = '\0'; \
    logfile << spaces << loginfo << std::endl; \
    spaces[indent] = ' '

同様に、3でインデントしたい場合

LOGGER(logfile, 3, "x=" << x << "   y=" << y << "   z=" << z);

C++ << は書式設定に関しては printf ほどエレガントではありませんが、可変引数を使用する問題を回避できます。

于 2014-05-25T10:13:58.037 に答える