为什么我的可变参数vsscanf函数有未定义的行为?

cbwuti44  于 2022-12-29  发布在  其他
关注(0)|答案(1)|浏览(157)

我创建了一个可变参数函数来解析可能有不同参数的字符串。在当前情况下,传入的字符串将是“38400,8,N,1\n”。

static int parse_response(const char *buff, char *format, ...){
    
    uint16_t retval=0;
    va_list arg_ptr;
    va_start(arg_ptr, format);

    retval = vsscanf((const char*)buff, format, arg_ptr);
    va_end(arg_ptr);
    return retval;
}

下面是我调用vsscanf函数的地方。

satel_return_typedef Satel_GetBaudrate(satel_typedef* Satel, uint32_t* Baudrate, uint32_t timeout_ms){
    
    int Len;
    Len = printf_SLCommandString(Satel->tx_data_buffer, Satel->max_size, "SL%%B?");
    uint8_t DataBits; char Parity; uint8_t StopBit;
    if(Len < 0 || Len > (int)Satel->max_size) {
        return R_API_ERROR;
    }
    if(Satel->Platform->Comm_Send(Satel->tx_data_buffer, Len, NULL)<0)
    return R_PLATFORM_ERROR;
    if(Satel_WaitForCommResponse(Satel,timeout_ms)==R_COMM_RESPONSE_VALUE){
        parse_response((char*)Satel->rx_data_buffer,"%d,%d,%c,%d\n", Baudrate, &DataBits, &Parity, &StopBit);
        return R_OP_SUCCESSED;
    }     
    return R_OP_ERROR;
}

我知道,有一些规则,不属于未定义的行为,但我的头脑混乱,哪些规则是打破这里.

typedef void (*Write_Enamod_Pin)(satel_power_typedef Config);
typedef void (*Write_Service_Pin)(satel_service_typedef Config);
typedef int32_t (*Send_Message)(const uint8_t *data_to_send, uint32_t bytes_to_send, void *custom); /* -1 IO Error*/
typedef int32_t (*Read_Message)(uint8_t *data_to_read, uint32_t bytes_to_read, void *custom); /* -1 IO Error*/
typedef uint32_t (*Get_TickCount)(void);
typedef void (*Delay_ms)(uint32_t milisec);
typedef struct{
    Write_Enamod_Pin    Power;
    Write_Service_Pin   Service;
    Send_Message        Comm_Send;
    Read_Message        Comm_Read;
    Get_TickCount       Get_TickCount;
    Delay_ms            Delay_Ms;
}satel_hw_typedef;
typedef struct{
    satel_state_typedef State;
    uint8_t*            tx_data_buffer;
    uint8_t*            rx_data_buffer;
    uint32_t            max_size;
    satel_hw_typedef*   Platform;
}satel_typedef;
ou6hu8tu

ou6hu8tu1#

格式说明符不匹配。
%d说明符需要一个int *。在你使用它的三个地方,你传递了一个uint32_t *,一个uint8_t *,和一个uint8_t *。这些不匹配触发了未定义的行为。
您需要使用u作为所有3个参数的无符号整数参数,并且您希望使用hh修饰符作为uint8_t(即unsigned char)参数。此外,您希望从格式字符串中删除\n,因为这会阻止阅读停止,直到您在按下 * Enter后按下其他非空白字符 *。

"%u,%hhu,%c,%hhu"

相关问题