広告

printf()関数(その3) C/C言語上級講座

printf()関数と云へば、先づ頭に浮かぶのは可変変数と云ふ特徴でせう。 printf()関数のやうな可変変数は、どうすれば実現できるのでせう。 int型ではなくvoid型のprintf()もどき関数prf()を作成してみませう。

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

void
prf (const char *format, ...)
{
	va_list list;

	va_start (list, format);

	(void)vprintf (format, list);

	va_end (list);
}

int
main (void)
{
	prf ("%d: Hello!\n", 5);

	return EXIT_SUCCESS;
}

可変引数の個数が分つてゐるときは、 formatではなくて、その個数をva_start()に指定できます。 え、型が違ふぢやないか、つて。 大丈夫です、va_start()はマクロ関数なので型確認はされません。 さて、ここからが上級講座。 GCCだけで使へるテクですが、prf()関数を次のやうに書き換えます。
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <assert.h>
#include <syslog.h>

__attribute__((format(printf,1,2))) void
prf (const char *format, ...)
{
	va_list list;

	assert (NULL != format);
	va_start (list, format);
		(void)vprintf (format, list);
		vsyslog (LOG_ERR, format, list);
	va_end (list);
}

かうしておいてGCCのオプションとして-Wformat=2を指定すると、 自作のprf()関数も本物のprintf()関数と同様に、 フォーマットにリテラルではなく変数を指定して呼び出すと 警告がでるやうになります。 なぜリテラルを指定しなければならないか、については、 「printf()関数 その1」を御覧ください。

Copyright © 皇紀2670 Ezo Labo. All Rights Reserved.
皇紀2670年05月20日更新
TOPへ