Linux講座にようこそ。このページは「C言語プログラミング入門 - 第14章.ライブラリ関数 - 入出力ライブラリ」です。

C言語プログラミング入門

14. ライブラリ関数(10/36) - 入出力ライブラリ(9/10)

14.13 書式出力(可変個引数)関数

ここで紹介する出力関数は引数が可変(可変個引数)であること以外は書式出力関数のfprintf関数printf関数sprintf関数と同じです。引数の可変部分は引数リストオブジェクト(引数リストを格納する領域)を指定しますが、これについては「可変個引数操作関数」をご覧下さい。

14.13.1 vfprintf関数

vfprintf関数はファイルポインタに対応したファイルに、書式制御文字列に従い編集した文字列を出力します。

【表14-1-37】 vfprintf関数
形式#include <stdarg.h>
int vfprintf(FILE *fp, const char *format, va_list ap);
返り値出力できた場合は出力文字数を返します。エラーが発生した場合は負の値を返します。
引数
FILE *fp
出力するファイルのファイルポインタを指定します。
const char *format
書式制御文字列を指定します。書式制御文字列についてはfprintf関数をご覧下さい。
va_list ap
引数リストオブジェクトを指定します。

14.13.2 vprintf関数

vprintf関数は書式制御文字列に従い編集した文字列を標準出力に出力します。

【表14-1-38】 vprintf関数
形式#include <stdarg.h>
int vprintf(const char *format, va_list ap);
返り値vfprintf関数と同じです。
引数
const char *format
書式制御文字列を指定します。
va_list ap
引数リストオブジェクトを指定します。

14.13.3 vsprintf関数

vsprintf関数は書式制御文字列に従い編集した文字列を引数に指定した変数に設定します。

【表14-1-39】 vsprintf関数
形式#include <stdarg.h>
int vsprintf(char *str, const char *format, va_list ap);
返り値vfprintf関数と同じです。
引数
char *str
編集結果を出力する文字列を指定します。
const char *format
書式制御文字列を指定します。
va_list ap
引数リストオブジェクトを指定します。

14.13.4 例題

肥満度(BMI)の計算を行い結果を表示します。オプションにより肥満度の診断を行い、「正常です。」「低すぎます。」「高すぎます。」のメッセージを付け加えます。結果の表示はVarMessage関数で行いますが、オプションによりメッセージが異なりますので可変個引数の関数にしていま0す。なお、第1引数は固定引数でオプションを文字で指定します。

  1. #include <stdio.h>
  2. #include <stdarg.h>
  3. /* 肥満状態を判定するための定数 */
  4. #define BMI_LIMIT_UNDER   18.5
  5. #define BMI_LIMIT_OVER    25.0
  6.  
  7. int main(void)
  8. {
  9.     /* 結果の表示間数 */
  10.     void VarMessage(char Check, ...);
  11.  
  12.     double  weight;
  13.     double  height;
  14.     double  bmi;
  15.     char    check;
  16.  
  17.     printf("肥満度(BMI)の計算を行います。\n");
  18.     printf("体重(kg)と身長(m)を入力してください ==> ");
  19.     scanf("%lf%lf", &weight, &height);
  20.  
  21.     /* 肥満度(BMI) = 体重(kg) / 身長(m) / 身長(m) */
  22.     bmi = weight / height / height;
  23.  
  24.     printf("診断結果を表示しますか(Y/N) ==> ");
  25.     scanf("%*c%c", &check);
  26.  
  27.     if(check == 'Y' || check == 'y')
  28.     {
  29.         if(bmi >= BMI_LIMIT_UNDER && bmi <= BMI_LIMIT_OVER)
  30.         {
  31.             VarMessage(check, bmi, "正常です。");
  32.         }
  33.         else if(bmi < BMI_LIMIT_UNDER)
  34.         {
  35.             VarMessage(check, bmi, "低すぎます。");
  36.         }
  37.         else
  38.         {
  39.             VarMessage(check, bmi, "高すぎます。");
  40.         }
  41.     }
  42.     else
  43.     {
  44.         VarMessage(check, bmi);
  45.     }
  46.     return 0;
  47. }
  48.  
  49. /* 結果の表示関数 */
  50. void VarMessage(char p_check, ...)
  51. {
  52.     char    *format;
  53.     va_list ap;
  54.  
  55.     /* 可変引数リストの初期化 */
  56.     va_start(ap, p_check);
  57.  
  58.     /* 書式の作成 */
  59.     if(p_check == 'Y' || p_check == 'y')
  60.     {
  61.       format = "BMI : %.2f(%s)\n";;
  62.     }
  63.     else
  64.     {
  65.       format = "BMI : %.2f\n";
  66.     }
  67.     /* メッセージ出力 */
  68.     vprintf(format, ap);
  69.  
  70.     /* 可変引数リストのリセット */
  71.     va_end(ap);
  72.  
  73.     return;
  74. }
$ ./ex14_1_12.prg
肥満度(BMI)の計算を行います。
体重(kg)と身長(m)を入力してください ==> 65.5 1.72
診断結果を表示しますか(Y/N) ==> y
BMI : 22.14(正常です。)
$
$ ./ex14_1_12.prg
肥満度(BMI)の計算を行います。
体重(kg)と身長(m)を入力してください ==> 65.5 1.55
診断結果を表示しますか(Y/N) ==> y
BMI : 27.26(高すぎます。)
$
$ ./ex14_1_12.prg
肥満度(BMI)の計算を行います。
体重(kg)と身長(m)を入力してください ==> 65.5 1.95
診断結果を表示しますか(Y/N) ==> y
BMI : 17.23(低すぎます。)
$
$ ./ex14_1_12.prg
肥満度(BMI)の計算を行います。
体重(kg)と身長(m)を入力してください ==> 65.5 1.72
診断結果を表示しますか(Y/N) ==> n
BMI : 22.14
$
10行目
可変個引数のVarMessage関数のプロトタイプ宣言です。第1引数は固定引数で診断オプションを指定します。(Yまたはyの場合に診断を行います)
31、35、39行目
診断結果を表示しますので、引数を3つ指定(第3引数に診断メッセージを指定)してVarMessage関数を呼び出します。
44行目
診断結果を表示しませんので、引数を2つ指定してVarMessage関数を呼び出します。
56行目
引数リストを準備(初期化)します。
68行目
vprintf関数でメッセージを標準出力に出力します。
71行目
引数リストをリセットします。