vsprintf(char *str, const char *format, va_list ap, ...)?

Discussion in 'C Programming' started by goldfita@signalsguru.net, May 15, 2006.

  1. Guest

    My last post -
    http://groups.google.com/group/comp.lang.c/browse_thread/thread/eacc2938b4c8ee66/0bdf6ab20a6007d0

    I have a little bit more challenging question this time. Suppose I
    have

    write_cmd(struct ast_connection *conn, char *msg, ...);

    I want to call it like (forgive the syntax)

    write_cmd(conn, str, p1, p2, ..., pn, k1, k2, ..., km);

    The parameters p1 to pn must be passed to write_cmd every time. The
    parameters k1 to km are not actually constant, but they are accessible
    from conn; so, I don't really need to pass them in. It would be better
    to call

    write_cmd(conn, str, p1, p2, ..., pn);

    However, as noted in the last post, I want to print the parameters
    using vsprintf, which means they all need to be in the list. I could
    follow vsprintf with sprintf to get the rest of k1 to Km, and thus
    roughly double both the buffer space and processing time. But this
    seems silly given that I could get those parameters into the list by
    calling the first write_cmd.

    I have some code which obviously doesn't work. But you can probably
    see what I'm aiming for. I could probably also do it with a vsprintf
    that took a list and a variable number of parameters, if there were
    such a thing...

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

    void vvfunc(char *msg, va_list argp, va_list argp2)
    {
    char buf[128];

    vsprintf(buf,msg,argp); //argp2 goes here
    puts(buf);
    }

    void vfunc2(char *msg, va_list argp, ...)
    {
    va_list argp2;

    va_start(argp2,argp);
    vvfunc(msg,argp,argp2);
    va_end(argp2);
    }

    void func(char *msg, ...)
    {
    va_list argp;

    va_start(argp,msg);
    vfunc2(msg,argp,10); //k1
    va_end(argp);
    }

    int main(void)
    {
    func("hello %s %d\n","there"); //p1
    return 0;
    }
     
    , May 15, 2006
    #1
    1. Advertising

  2. Guest

    I don't think there's any way to do this portably. The only solution I
    can think of is to implement your own vvsprintf() function which takes
    two va_lists.
     
    , May 15, 2006
    #2
    1. Advertising

  3. Guest

    wrote:
    > I don't think there's any way to do this portably. The only solution I
    > can think of is to implement your own vvsprintf() function which takes
    > two va_lists.


    Darn, that's kind of what I figured. I thought about implementing a
    vvsprintf, but it's not worth it.
     
    , May 15, 2006
    #3
  4. kyle.tk Guest

    wrote:
    > My last post -
    > http://groups.google.com/group/comp.lang.c/browse_thread/thread/eacc2938b4c8ee66/0bdf6ab20a6007d0
    >
    > I have a little bit more challenging question this time. Suppose I
    > have
    >
    > write_cmd(struct ast_connection *conn, char *msg, ...);
    >
    > I want to call it like (forgive the syntax)
    >
    > write_cmd(conn, str, p1, p2, ..., pn, k1, k2, ..., km);
    >


    Variable lists are, well, variable. There would be no way to know where
    the first variable list ends and the next one begins.

    va_arg lists always have to have "..." as the last argument in the
    function argument list.

    -kyle
     
    kyle.tk, May 15, 2006
    #4
  5. Guest

    There is a portable way to do it.
    Replace va_arg lists by arrays and use initializers to init. the arrays
    before the function call:

    write_cmd(Connection_t* conn, char* str,
    PParameter_t p[], int p_size,
    KParameter_t k[], int k_size) ;
    ....
    KParameter_t k[] = {{INT,1}, {INT,2}};
    ....
    write_cmd(conn, str, p, p_size, k, SIZEOF(k)) ;
    ....


    See example:
    #include <stdio.h>

    #define SIZEOF(array) \
    sizeof(array) / sizeof((array)[0])

    /*NOTE: belowed struct/union(s) members' names make no sense.
    They have taken just for example.
    */
    typedef enum{
    FAKE_ARRAY, INT, STRING
    } Typecode; /* use the same Typecode type in both
    PParameter and KParameter for simplicity */

    typedef struct Connection{
    /* ... */
    int fake_int;
    char* fake_pchar;
    } Connection_t;


    typedef struct PParameter {
    Typecode type;
    union{
    /* ... */
    int fake_array[2];
    char* fake_pch;
    } u;
    } PParameter_t;

    typedef struct KParameter {
    Typecode type;
    union{
    /* ... */
    int int_fake;
    char* pchar_fake;
    } u;
    } KParameter_t;

    void
    write_cmd(Connection_t* conn, char* str,
    PParameter_t p[], int p_size,
    KParameter_t k[], int k_size) {
    int i;

    printf("str: \t%s\n", str);

    /* print p[] */
    printf("p: ");
    for (i = 0; i < p_size; ++i)
    switch(p.type) {
    case STRING:
    printf("\tstring: %s\n", p.u.fake_pch);
    break;
    case FAKE_ARRAY:{
    int j;
    printf("\tarray: ");
    for(j = 0; j < SIZEOF(p.u.fake_array); ++j)
    printf("%d, ", p.u.fake_array[j]);
    printf("\n");
    break;
    }
    };

    /* print k[] */
    printf("k: ");
    for (i = 0; i < k_size; ++i)
    switch(k.type) {
    case INT:
    printf("\tint: %d\n", k.u.int_fake);
    break;
    case STRING:
    printf("\tstring: %s\n", k.u.pchar_fake);
    break;
    };
    }
    int main() {
    Connection_t conn;
    /* Tested on:

    Comeau C/C++ 4.3.3 (Aug 6 2003 15:13:37) for
    ONLINE_EVALUATION_BETA1
    MODE:strict errors C99

    And:

    gcc.exe (GCC) 3.4.4 (mingw special)
    default compiler settings
    */
    PParameter_t p[] = {{STRING, .u.fake_pch = "a string"},
    {FAKE_ARRAY, {1,10}},
    {STRING, .u.fake_pch = "another string"}
    }; /* C99 mode initializer used */
    KParameter_t k[] = {{INT,1}, {INT,2}};

    write_cmd(&conn, "just a string", p, SIZEOF(p), k, SIZEOF(k));
    }
     
    , May 15, 2006
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. January Weiner

    Clever vsprintf

    January Weiner, Apr 21, 2004, in forum: C Programming
    Replies:
    3
    Views:
    403
  2. Thomas Rogg

    vsprintf - safe alternative?

    Thomas Rogg, Aug 18, 2004, in forum: C Programming
    Replies:
    5
    Views:
    1,085
    Moonie
    Aug 25, 2004
  3. Replies:
    24
    Views:
    838
    Netocrat
    Oct 30, 2005
  4. lovecreatesbeauty
    Replies:
    1
    Views:
    1,061
    Ian Collins
    May 9, 2006
  5. Javier
    Replies:
    2
    Views:
    566
    James Kanze
    Sep 4, 2007
Loading...

Share This Page