これは、何らかの形ですでに行われているが、例えばprintf()
は、このような仕組みを持っている、である私は、発信者
によって渡されたパラメータのvar_argument関数内のsprintfをしたいと言います。可変引数関数の場合は、可変パラメータの一部ではない最初のパラメータが必要です。フォーマット文字列として使用して、xの位置をnに設定します。
最初のパラメータは必須なので、そのようなパラメータを持つ必要があります。可変引数で何を期待するかを示す指標として自然なようです。
は、一例として、これを持っもちろん
#include <stdio.h>
#include <stdarg.h>
int
variable(const char *format, ...)
{
va_list args;
int count;
va_start(args, format);
count = 0;
while (*format != '\0') {
switch (*format++) {
case 's':
fprintf(stdout, "arg[%d]: %s\n", count, va_arg(args, const char *));
break;
case 'd':
fprintf(stdout, "arg[%d]: %d\n", count, va_arg(args, int));
break;
case 'f':
fprintf(stdout, "arg[%d]: %f\n", count, va_arg(args, double));
break;
}
count += 1;
}
va_end(args);
return 0;
}
int
main(void)
{
variable("sdf", "Example", 3, 3.1416);
}
、指定子と引数の実際の型の間の不一致は、未定義の動作に、望ましくない行動に論理的帰結としてつながります。したがって、非常に注意しなければならないか、またはprintf()
スタイル指定子を使用し、そのような不一致が発生した場合に警告するようにコンパイラに指示します。
もう1つの解決策は、glibの関数のようなものです。型指定子を渡し、パラメータの直後にパラメータの最後を示す最後の値を渡します。パラメータは、 "指定子は" この
#include <stdio.h>
#include <stdarg.h>
enum types {
String, Integer, Double, Float = Double, /* unless you want to store the value in a poitner
* there is normally no difference between these
*/
End
};
int
variable(enum types type, ...)
{
va_list args;
int count;
va_start(args, type);
count = 0;
while (type != End) {
switch (type) {
case String:
fprintf(stdout, "arg[%d]: %s\n", count, va_arg(args, const char *));
break;
case Integer:
fprintf(stdout, "arg[%d]: %d\n", count, va_arg(args, int));
break;
case Double:
fprintf(stdout, "arg[%d]: %f\n", count, va_arg(args, double));
break;
default:
fprintf(stderr, "unknown type specifier\n");
break;
}
type = va_arg(args, enum types);
count += 1;
}
va_end(args);
return 0;
}
int
main(void)
{
variable(String, "Example", Integer, 3, Double, 3.1416, End);
}
などのすべてのサポートされているタイプを、列挙
enum
あなたは 'のprintf()'知っていますだろうか? –引数の型を与えるには別のパラメータが必要です。これは唯一の(移植可能な)方法です。 ( '%d'、'%f'、...)形式から型を推測する 'printf'のようなものです。 – Holt
'...'の前にある引数は、伝統的に型を示すものであり、サイズはその型から推測されます。 –