How to use va_list and va_end with pointers?

I'm having a problem implementing a function with a variable argument list. The mqtt_get_payload function must be an "extension" of the sscanf function.

Initially, the function receives an char array and appends a '\0' character. This turns the vector into a string. This string is then passed as the first argument to sscanf. I don't understand why, but it generates a segmentation fault. (See the code that follows.)

The code that follows does the same thing my function should do, but... no problem... no segmentation fault.

sscanf(mqtt_payload2str(msg, strlen(msg)),"Temp = %f C, Humidity = %f %%",&Temp,&Humidity);

I put the complete code just below. Can anyone see where the bug is?

#include "string.h"
#include "stdio.h"
#include "stdarg.h"

#define MQTT_BUF_PAYLOAD_LEN    512

static char mqtt_buf_payload[MQTT_BUF_PAYLOAD_LEN];

char* mqtt_payload2str(char *payload, int len)
{
    /* The next line of code inserted a '\0' at the end of the string. */
    snprintf(mqtt_buf_payload, MQTT_BUF_PAYLOAD_LEN, "%.*s", len , payload);

    return mqtt_buf_payload;
}

int mqtt_get_payload(char *payload, int len, char *fmt,...)
{
    va_list  argptr;                      

    va_start( argptr, fmt );             

    /* Inseri o caractere '\0' no fim da string */
    snprintf(mqtt_buf_payload, MQTT_BUF_PAYLOAD_LEN, "%.*s", len , payload);
    int ret = sscanf(mqtt_buf_payload,fmt,argptr);

    va_end( argptr );                     

    return ret;
}

int main(void)
{
    char msg[] = "Temp = 11 C, Umidade = 12 %";
    float Temp, Umidade;

   while(1){
       // The next line of code works perfectly.
       sscanf(mqtt_payload2str(msg, strlen(msg)),"Temp = %f C, Umidade = %f %%",&Temp,&Umidade);
       // Next line of code causes segmentation fault
       mqtt_get_payload(msg, strlen(msg), "Temp = %f C, Umidade = %f %%",&Temp,&Umidade);
       printf("Temp=%fC, Umidade=%f%%\n",Temp, Umidade);
   }

   return 0;
}

Solution 1:

There are special functions which start with v

vsscanf

int vsscanf ( const char * s, const char * format, va_list arg );

Use them if you want to pass va_list