プログラムをデバッグする際に必ずと言っていいほど使うデバッグログ。
ログの内容と発生個所(発生したソースファイル名と行番号)がわかればデバッグするのに非常に役立ちます。
今回はC言語の可変長引数を利用して、printf関数と同じフォーマットで発生したソースファイル名と行番号がわかるデバッグ文を出力するコードを作成します。
C言語で可変長引数を使ってデバッグログを表示させる方法
まず、ここで言う可変長引数ですが例えばprintf関数の引数の数、決まってませんよね。
決まっているのは第1引数に出力するフォーマット文字列、第2引数以降にそのフォーマット文字列で利用されている書式に対応するデータです。
引数の数は1個以上で、第2引数以降は利用する内容によって変化します。
このような引数のことを可変長引数と言います。
可変長引数の宣言
C言語での可変長引数の宣言は以下のように行います。
void func( char *fmt, ... ) ;
上記の「…」の部分が可変長引数になります。
可変長引数の部分の引数の数は0以上になります。
可変長引数を使ったデバッグログ
では実際に可変長引数を使ったデバッグログのソースを作ってみます。
#include #include #include /*デバッグ表示マクロ*/ #define DEBUG_PRINT( fmt, ... ) debugPrint( __FILE__, __LINE__, fmt, __VA_ARGS__ ) /*Prototype宣言*/ void debugPrint( char*, int , char*, ... ) ; int main( int argc, char **argv ) { DEBUG_PRINT( "%d\n", 30 ) ; /*デバッグ文出力*/ DEBUG_PRINT( "%s,%d\n", "ABCD" ,2000 ) ; /*デバッグ文出力*/ DEBUG_PRINT( "%s,%d,%d\n", "abcd" ,1, 50 ) ; /*デバッグ文出力*/ return 0 ; } void debugPrint(char *fname, int line, char *fmt, ...) { /*変数宣言*/ char wk[ 1024 ] ; int len = 0 ; /*呼び足元のファイル名と行数を展開*/ sprintf( wk, "[%s][%d]", fname, line ); len = strlen( wk ) ; /*可変子引数を展開*/ va_list ap; va_start( ap, fmt ); vsprintf( &wk[len], fmt, ap ); va_end( ap ); /*デバッグ文を表示*/ printf( wk ); return ; }
実際にこのデバッグ出力を呼び出す関数(マクロ)は「DEBUG_PRINT」になり、その関数(マクロ)の実態は「debugPrint」になります。
今回は可変長引数を展開するのに「__VA_ARGS__、va_list、va_start,va_end」マクロを利用しました。
今回は_FILE__と__LINE__を入れこみたかったので2重構造の関数になっています。
_FILE__と__LINE__に関しては以下の記事を参照してください。
[st-card id=5047 ]
このプログラムの実行結果は以下のようになります。
[..\main.c][13]30 [..\main.c][14]ABCD,2000 [..\main.c][15]abcd,1,50
最初にファイル名とその行番号が出力され、そのあとにprinitf関数と同様の可変長引数で指定された内容が出力されています。
まとめ
C言語の可変長引数を展開は「,…」で宣言し、「va_list、va_start、va_end」マクロを利用すれば簡単に実現することができます。
これでデバッグやエラーが発生したファイル名とその行番号がわかるデバッグログが出力でます。
以上、「C言語で可変長引数を使ってデバッグログを表示させる方法」でした。