C言語入門講座。関数、サンプル集を参考にして、 C言語をマスターしよう。初心者から上級者まで。

可変引数リストの値を書式に従い出力する

2012.08.10

vprintf関数、vfprintf関数、vsprintf関数は、可変引数リストで指定した値を書式に従い、文字列に編集(変換)します。

これらの関数は可変引数リストを用いた点以外は、printf関数、fprintf関数、sprintf関数と同じです。

#include <stdio.h>
#include <stdarg.h>
int vprintf(const char *format, va_list ap);
int vfprintf(FILE *stream, const char *format, va_list ap);
int svprintf(char *str, const char *format, va_list ap);

*format(書式)は第3引数で指定する可変引数リストの値の編集形式を指定します。
apは可変引数リストを格納する領域を指定します。
*strは編集した結果を格納するための領域を指定します。

戻り値として、正常に出力できた場合は出力した文字数が、エラーの場合は負の値を返します。

*format(書式)はprintf関数やfprintf関数と同じですので、fprintf関数をご覧ください。また、可変引数リストに付いてはva_arg関数、va_start関数、va_end関数をご覧ください。

プログラム 例

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

void OutputLog(FILE *, int, ...);      /* ログファイルの出力 */
char *GetDate(void);                   /* 実行日時の取得 */
char *StrChomp(char *);                /* 改行削除 */

int main()
{
  FILE    *fp;
  char    message[100];

  if ((fp = fopen('mess.log', 'a')) == NULL) {
    fprintf(stderr, 'ログファイルが開けません\n');
    abort();
  }

  OutputLog(fp, 2, 'var_printf', '開始');

  while(1) {
    printf('メッセージを入力してください ==> ');
    fgets(message, 100, stdin);
    StrChomp(message);

    if (strcmp(message, 'end') != 0) {
      OutputLog(fp, 1, message);
    }
    else {
      break;
    }
  }

  OutputLog(fp, 2, 'var_printf', '終了');
  fclose(fp);

  return 0;
}

/* ログファイルの出力 */
void OutputLog(FILE *p_fp, int p_num, ...)
{
  va_list     ap;
  char        format[50] = '%s';
  int         cnt;

  fprintf(p_fp, '%s : ', GetDate());

  /* 書式作成 */
  for (cnt = 1; cnt < p_num; ++cnt) {
    strcat(format, ' : %s');
  }
  strcat(format, '\n');

  /* 可変引数リストの初期化 */
  va_start(ap, p_num);
  /* 可変引数リストの出力 */
  vfprintf(p_fp, format, ap);
  /* 可変引数リストのリセット */
  va_end(ap);
}

/* 実行日時の取得 */
char *GetDate()
{
  time_t           t;

  t = time(NULL);
  return StrChomp(ctime(&t));
}

/* 改行削除 */
char *StrChomp(char *str)
{
  char   *str_p;;

  for (str_p = str; *str_p; ++str_p)
    ;

  if (*(str_p - 1) == '\n') {
    *(str_p - 1) = '\0';
  }

  return str;
}

例の実行結果

$ ./var_printf.exe
メッセージを入力してください ==> こんにちは。
メッセージを入力してください ==> 良いお天気ですね。
メッセージを入力してください ==> ご機嫌よう。
メッセージを入力してください ==> end
$
$ ./var_printf.exe
メッセージを入力してください ==> 今晩は。
メッセージを入力してください ==> お久しぶりです。
メッセージを入力してください ==> お休みなさい。
メッセージを入力してください ==> end
$
$ cat mess.log
Fri Jul 11 14:38:30 2008 : var_printf : 開始
Fri Jul 11 14:38:44 2008 : こんにちは。
Fri Jul 11 14:39:04 2008 : 良いお天気ですね。
Fri Jul 11 14:39:26 2008 : ご機嫌よう。
Fri Jul 11 14:39:32 2008 : var_printf : 終了
Fri Jul 11 14:40:24 2008 : var_printf : 開始
Fri Jul 11 14:40:50 2008 : 今晩は。
Fri Jul 11 14:41:05 2008 : お久しぶりです。
Fri Jul 11 14:41:45 2008 : お休みなさい。
Fri Jul 11 14:41:48 2008 : var_printf : 終了
$

関連記事