2012-04-23 31 views
0

私の関数ptr * Os_printf * では2つ以上の引数を出力できますが、私の関数は1つの引数でしか機能しません。例えば関数ポインタの引数リスト

- >

Os_printf("Moon %d %d",55,5); 

OUT:

月55 5

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

char db[50]; 

void test_1(int (*debug)()) 
{ 
    debug("JOY %d %d \n",4,55); 
} 

volatile int (*ptr_fscreener)(char * __restrict, const char * __restrict, ...); 

void Os_formater(int (*debug)()) 
{ 
    ptr_fscreener=debug; 
} 

void Os_printf(const char * __restrict out,void**d) 
{ 
va_list args; 
char db[50]; 
ptr_fscreener(db,out,d); 
puts(db); 
} 

int main(void) { 
    Os_formater(sprintf); 
    Os_printf("Moon %d",55); 
    test_1(printf); 
    puts("!!!Hello World!!!"); /* prints !!!Hello World!!! */ 
    return EXIT_SUCCESS; 
    } 


/******* OUTPUT For example ******/ 
     Moon 55 
     JOY 4 55 
     !!!Hello World!!! 
+2

、答えは非常に単純です:のhttp:// WWW。 gnu.org/software/libc/manual/html_node/Variadic-Functions.htmlしかし、あなたの言葉遣いは質問ではなく、声明です。それは伝えにくいです。 – tbert

答えて

3

あなたは、他の多くの変化の中で、<stdarg.h>おそらくvsnprintf()を使用する必要があります。

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

void test_1(int (*debug)(const char *format, ...)) 
{ 
    debug("JOY %d %d\n",4,55); 
} 

static int (*ptr_fscreener)(char *, size_t, const char *, va_list); 

void Os_formatter(int (*debug)(char *buffer, size_t buflen, const char *format, va_list args)) 
{ 
    ptr_fscreener = debug; 
} 

void Os_printf(const char *out, ...) 
{ 
    va_list args; 
    char db[50]; 
    va_start(args, out); 
    ptr_fscreener(db, sizeof(db), out, args); 
    va_end(args); 
    puts(db); 
} 

int main(void) 
{ 
    Os_formatter(vsnprintf); 
    Os_printf("Moon %d",55); 
    test_1(printf); 
    puts("!!!Hello World!!!"); 
    return EXIT_SUCCESS; 
} 

vsnprintf()を使用すると、正しく使用する限り、バッファオーバーフローに対する保護が得られます。 vsnprintf()に戻すことはかなり簡単です。 snprintf()またはsprintf()を確実に使用することはできないと思います。

編集:

gcc -O3 -g -std=c99 -Wall -Wextra va.c -o va 

結果:あなたは "?どのように私は自分の可変引数の関数を作るのですか" 求めている場合は

Moon 55 
JOY 4 55 
!!!Hello World!!! 
+0

'char db [50];を2回定義します。以前の定義が必要ですか?私はあなたがこの点に満足に答えると答えをアップアップします。 – Blaisorblade

+0

@Blaisorblade:グローバル変数 'db'は必要ありません。未使用です。私は単にそれを削除することを忘れました。私の唯一の言い訳は、それは元々(それは多くの言い訳ではない)、それはどんな害も及ぼさなかったことです(これは正しい言い訳ではありませんが、正確です)。 –

+0

あなたは正しいです、私は気づいていませんでした。あなたは私の投票権を持っています。 – Blaisorblade

関連する問題