[PR] この広告は3ヶ月以上更新がないため表示されています。
ホームページを更新後24時間以内に表示されなくなります。
stdarg、標準引数とでもいいましょうか。知っておくとちょっと便利な機能です。
printfの定義は、
int printf(const char *format, ...);
となっていますが、このような、一番最後の「...」を表現するのにstdargを使用します。
とりあえず、「...」を引数とした関数を作ってみましょう。
int function(const char *text, ...){ /* 処理省略 */ return 0; }
とりあえず、できました。呼び出す方は、function("a","b","c","d")など、適当に引数を並べることができます。問題は、function内部で、いかに引数を取り出すか、です。
最初の引数は*textなので、取り出せます。
2番目以降の引数、つまり「...」の部分は、va_startによって、va_list型の値として取り出せます。
void va_start(va_list ap, argN);
argNには「...」の前の引数、この場合では、「text」をセットします。
#include <stdarg.h> /* その他省略 */ /* main関数省略 */ int function(const char *text, ...){ va_list ap; /* va_list型変数 */ va_start(ap, text); /* 処理省略 */ return 0; }
va_listから適当な型で引き出すにはva_argを使用します。
type va_arg(va_list ap, type);
#include <stdarg.h> /* その他省略 */ /* main関数省略 */ int function(const char *text, ...){ const char* text2; va_list ap; /* va_list型変数 */ va_start(ap, text); text2 = va_arg(ap, const char*); /* 処理省略 */ return 0; }
va_listをクローズするのは、va_endです。
void va_end(va_list ap);
#include <stdarg.h> #include <stdio.h> /* その他省略 */ /* main関数省略 */ int function(const char *text, ...){ const char* text2; va_list ap; /* va_list型変数 */ va_start(ap, text); text2 = va_arg(ap, const char*); va_end(ap); printf("%s, %s\n", text, text2); return 0; }
function("abc","def")で呼び出してみると、
abc, def
と、表示してくれます。
va_listから適当な型の変数を取り出して表示する例をやりましたが、stdio.hに定義されている、vprintfなどを使えば、va_list型をそのまま使って入出力することができます。
int vfprintf(FILE *stream, const char *format, va_list ap); int vprintf(const char *format, va_list ap); int vsnprintf(char *s, size_t n, const char *format, va_list ap); int vsprintf(char *s, const char *format, va_list ap);
内容は、fprintf、printf、snprintf、sprintfと同じで、va_listを使うところが異なっています。↓のようにすれば、printfとほぼ変わらない関数になります。画面出力にプラスアルファしたいときに使えます。
#include <stdarg.h> #include <stdio.h> /* その他省略 */ /* main関数省略 */ /* 「printf」とほぼ同じ関数 */ int function(const char *text, ...){ va_list ap; /* va_list型変数 */ va_start(ap, text); vprintf(text, ap); va_end(ap); return 0; }
また、vsprintfなどを使えば、フォーマット済み文字列を作成できるので、関数呼び出し元でフォーマット済み文字列を作成する必要がなく、関数内でフォーマットし、別の文字列引数の関数に渡すということもできます。