Thread: Variable function arguments.

  1. #1
    Registered User
    Join Date
    May 2011
    Posts
    53

    Variable function arguments.

    I want to use variable arguments
    Code:
    void va_test(int num_args, ...)
    {
        va_list valist; 
        
        va_start(valist, num_args); 
        
       for (int i = 0; i <= num_args; i++)
           int sum += va_arg(valist, int);
    }
    But what if the arguments have different types
    Code:
    va_test(4, 1, "aa" , 2, "bb" );
    How can I check the data type?
    Code:
    void va_test(int num_args, ...)
    {
        va_list valist; 
        
        va_start(valist, num_args); 
        
       for (int i = 0; i <= num_args; i++)
      {
           //if arg is int
           int sum = va_arg(valist, int);
           //if arg is string
           char *str = va_arg(valist, char *);
      }
    }
    Last edited by john7; 02-19-2020 at 04:56 AM.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,548
    You would do something like what the printf family of functions does: have a known parameter that describes the types of the variable arguments. In the case of printf, it is a format string with prescribed format specifiers, but of course you could take your own approach.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    May 2011
    Posts
    53
    Quote Originally Posted by laserlight View Post
    You would do something like what the printf family of functions does: have a known parameter that describes the types of the variable arguments. In the case of printf, it is a format string with prescribed format specifiers, but of course you could take your own approach.
    I see. Like %s tells it's a string. Thank you.

  4. #4
    Registered User
    Join Date
    May 2011
    Posts
    53
    I did it this way

    Code:
    typedef struct
    {
        void *value;
        int type;
    }VAR;
    
    void MyPrintf(int argc, ...)
    {
        int i;
        int val;
        char *strp;
        VAR var;
        
        va_list valist; 
        
        va_start(valist, argc); 
        
        //first argument is a resulting string
        char *string = va_arg(valist, char *);
       
        for (i = 1; i < argc; i++)
        {
            var = va_arg(valist, VAR);
            switch (var.type)
            {
                case VTYPE_BYTE:  val = *(uint8_t *)var.value;  break;
                case VTYPE_SHORT: val = *(uint16_t *)var.value; break;
                case VTYPE_INT:   val = *(uint32_t *)var.value; break;
                case VTYPE_STR:   strp = (char *)var.value;     break;
            }
            
            if (var.type < VTYPE_STR)
            {
                strp = loc_itoa(val);
                strcat(string, strp);
            }
            else
               strcat(string, strp);     
        }
        
       strcat(string, "\0");
       
       va_end(valist); 
    }
    Then I check
    Code:
    uint32_t COM_Printf()
    {
      char str[128] = { '\0' };
        
        VAR vars[4];
        
        vars[0].type = 1;
        vars[0].value = (uint8_t*)1;
        vars[1].type = 4;
        vars[1].value = (char *)"aa";
        vars[2].type = 3;
        vars[2].value = (uint32_t*)1234;
        vars[1].type = 4;
        vars[1].value = (char *)"bb\r";
        
       //I wish it would work like this but it doesn't
       //MyPrintf(5, str, vars);
    
       MyPrintf(5, str, vars[0], vars[1], vars[2], vars[3]);
       
       USART_SendString(SYS_USART, str);
          
       return MSG_OK;
    }
    I should see 1aa1234bb
    but I see
    87bb
    29491202949120

  5. #5
    Registered User
    Join Date
    May 2011
    Posts
    53
    This way it works
    Code:
    void MyPrintf(int argc, ...)
    {
        int i;
        int val;
        char *strp;
        VAR var;
        
        va_list valist; 
        
        va_start(valist, argc); 
        
        //first argument is a resulting string
        char *string = va_arg(valist, char *);
       
        for (i = 1; i < argc; i++)
        {
            var = va_arg(valist, VAR);
      
            switch (var.type)
            {
                case VTYPE_BYTE:  
                case VTYPE_SHORT:
                case VTYPE_INT:
                  val = (int)var.value;
                 break;
                
                case VTYPE_STR:
                  strp = (char *)var.value; 
                  break;
            }
       
            if (var.type < VTYPE_STR)
            {
                strp = loc_itoa(val);
                strcat(string, strp);
            }
            else
               strcat(string, strp);     
        }
        
       strcat(string, "\0");
       
       va_end(valist); 
    }
    
    uint32_t COM_Printf()
    {
      char str[128] = { '\0' };
        
        VAR vars[4];
        
        vars[0].type = VTYPE_BYTE;
        vars[0].value = (void *)1;
        vars[1].type = VTYPE_STR;
        vars[1].value = (void *)"aa";
        vars[2].type = VTYPE_INT;
        vars[2].value = (void *)1234;
        vars[3].type = VTYPE_STR;
        vars[3].value = (void *)"bb\r";
        
       MyPrintf(5, str, vars[0], vars[1], vars[2], vars[3]);
       
       USART_SendString(SYS_USART, str);
          
       return MSG_OK;
    }
    Last edited by john7; 02-19-2020 at 09:13 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Prototype for a function accepting variable arguments
    By techie_san778 in forum C Programming
    Replies: 3
    Last Post: 12-06-2014, 11:49 AM
  2. Function with variable number of arguments
    By andrewg in forum C Programming
    Replies: 9
    Last Post: 12-18-2010, 09:19 PM
  3. function with variable arguments crashes
    By spongefreddie in forum C Programming
    Replies: 7
    Last Post: 11-18-2010, 03:44 PM
  4. variable number of arguments for a function or a macro
    By mynickmynick in forum C Programming
    Replies: 5
    Last Post: 05-19-2010, 11:35 AM
  5. Variable number of arguments in function.
    By kamoda_pawel in forum C Programming
    Replies: 1
    Last Post: 01-18-2007, 07:18 AM

Tags for this Thread