2017-10-03 6 views
0

さまざまな型の引数をさまざまに取る関数を作りたいと思います。私の問題は、どのように引数型を解析できるかです。同様の呼び出し側は、任意の型の引数を任意の順序で渡すことができます(書式指定子を指定せずに)。だから私はどのようにタイプを区別することができます呼び出し関数で。さまざまな型の引数をcで渡す

呼び出し側が渡したすべての値を関数var_argumentに出力するにはどうすればいいですか?

レッツは、ここに私のCコード

#include <stdio.h> 
#include <stdarg.h> 
void var_argument(int num,...); 

int main() 
{ 
var_argument(3,"Hello",7.87f,6); 
var_argument(3,7.87f,"Hello",6); 
return 0; 
} 

void var_argument(int num,...) 
{ 
char str[80]; 
/* What code should I write to differentiate between types and to print all the values passed by the caller */  

va_list list; 
va_start(list,num); 

/* How to do sprintf of the parameter passed to this function and store 
the formatted output in the array str */ 
} 
+0

などのすべてのサポートされているタイプを、列挙enumあなたは 'のprintf()'知っていますだろうか? –

+0

引数の型を与えるには別のパラメータが必要です。これは唯一の(移植可能な)方法です。 ( '%d'、'%f'、...)形式から型を推測する 'printf'のようなものです。 – Holt

+0

'...'の前にある引数は、伝統的に型を示すものであり、サイズはその型から推測されます。 –

答えて

0

これは、何らかの形ですでに行われているが、例えば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); 
} 
関連する問題