0

在 ble_app_template 的 on_ble_evt(ble_evt_t*) 函数中,我添加了“BLE_GATTS_EVT_WRITE”的案例。其中有以下代码:

    case BLE_GATTS_EVT_WRITE:
    { 
        ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
        SEGGER_RTT_printf(0, "Length = %d \n", p_evt_write->len);
        int n;
        char* buf2 = "";    
        char* buf3 = "";    
        count += p_evt_write->len;
        for(n=0; n<p_evt_write->len; n++)
        {
                   SEGGER_RTT_printf(0, "Received[%d] : %X \n", n, p_evt_write->data[n]);
                   SEGGER_RTT_printf(0, "Received[%d] : %d \n", n, p_evt_write->data[n]);
                   if(n>0){                                                     
                       sprintf(buf2, "%s", ((char*)p_evt_write->data[n]));    
                       strcat(buf3, buf2);
                   }                                                    
                   else{                                                
                       sprintf(buf2, "%s", ((char*)p_evt_write->data[n]));   
                       strcpy(buf3, buf2);
                   }
                   SEGGER_RTT_printf(0, "buf2 string: %s \n", buf2);
                   SEGGER_RTT_printf(0, "buf2 hex: %X \n", buf2[0]);
                   SEGGER_RTT_printf(0, "buf3 in string: %s \n", buf3);
                   SEGGER_RTT_printf(0, "count: %d \n", count);
        }
   }

我从存储在 p_evt_write->data[n] 中的 BLE 接收十六进制值。我想将所有这些接收到的十六进制值连接成一个字符串,将其存储在“buf2”中。

但是我在 sprintf 行收到错误。当我在 sprintf 中输入“%X”时,这些值不会转换为字符串,因为 buf2/buf3 字符串不会打印任何内容。目前的代码

sprintf(buf2, "%s", ((char*)p_evt_write->data[n]));

返回错误“错误:从不同大小的整数转换为指针 [-Werror=int-to-pointer-cast]”。如果我删除了 (char*) 类型转换,它会返回错误“错误:格式 '%s' 需要类型为 'char *'' 的参数。

我看到 p_evt_write->data[n] 其中 data 被声明为

uint8_t                     data[1];

我目前正在使用 Nordic 的 nRF51DK 与 Eclipse IDE 和 SEGGER RTT JLink 进行调试。所有打印都打印到 SEGGER RTT。(printf 不起作用,改用 SEGGER_RTT_printf 打印)

如何成功地将所有十六进制值连接在一起形成一个字符串?谢谢你。

4

2 回答 2

1

要附加到缓冲区,您可以使用以下内容:

size_t total_len = 0;
uint8_t buf = NULL;

while (receive()) {
    size_t len = p_evt_write->len;
    buf = realloc(buf, total_len + len);
    memcpy(buf + total_len, p_evt_write->data, len);
    total_len += len;
}

要将数组转换uint8_t为以 NUL 结尾的字符串,请分配足够的空间,复制字节并附加 NUL。

char* s = malloc(total_len + 1);
memcpy(s, buf, total_len);
s[total_len] = 0;

当然,如果 的任何元素buf是 NUL ( 0),您将出现截断字符串。没有办法解决这个问题(没有摆脱 NUL)。


请注意,->data它不包含“十六进制值”。十六进制是数字的文本表示。你没有十六进制;你有数字。这很好,因为这意味着不需要转换。您只需要复制字节并添加 NUL。

请注意,您遇到的特定错误是因为您将uint8_t(数字)转换为char*(指针)。这是没有意义的。您可能会选择(char*)(&(p_evt_write->data[n])),但这也行不通,因为%s不仅期望指向字符的指针,而且期望指向以 NUL 字符结尾的序列的第一个字符的指针。

于 2017-11-05T05:14:08.600 回答
0

假设您想要获取您收到的数据的十六进制表示的字符串,请尝试这样的事情......

    ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
    char* buf2 = malloc((p_evt_write->len * 2) + 1);
    memset(buf2, 0, (p_evt_write->len * 2) + 1);
    for(int n=0; n<p_evt_write->len; n++)
    {
        char buf3[10];
        sprintf(buf3, "%02X", (unsigned int)p_evt_write->data[n]);
        strcat(buf2, buf3);
    }
    SEGGER_RTT_printf(0, "buf2 string: %s \n", buf2);
    free(buf2);
于 2017-11-05T05:20:32.397 回答