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

标签 c scanf

我创建了一个可变参数函数来解析可能具有不同参数的字符串。 在当前情况下,传入字符串将为“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;

最佳答案

格式说明符不匹配。

%d 格式说明符需要一个 int *。在您使用它的 3 个地方,您传递了一个 uint32_t *、一个 uint8_t * 和一个 uint8_t *。这些不匹配会触发未定义的行为。

您需要使用 u 作为所有 3 个无符号整数参数,并且您希望使用 hh 修饰符作为 uint8_t (即 unsigned char) 参数。另外,您希望从格式字符串中删除 \n,因为这样可以防止读取停止,直到您按 ENTER 后按其他非空白字符

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

关于c - 为什么我的可变参数 vsscanf 函数有未定义的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74921271/

相关文章:

C程序只工作一部分

c - 有没有办法#define 一个只在Eclipse 编辑器窗口中定义的C 宏?

c - 我需要一种在 C 中两次读取 float 的方法。每次都以 <Ctrl>-d 结束

c - 为什么 printf() 在使用指针时绕过分段失败?

c - CodeBlocks IDE 中的 C 语言中的 Scanf 函数有问题吗?

c - 为什么 BSS 中静态数组的第二个循环比第一个更快?

C - argc 随操作而变化

检查 'make'包括哪些文件

c - fgets() 和 sscanf() 只存储数组中的第一个整数

c - scanf() 中的 %*c - 这是什么意思?