从 BLE 接收的数据无法从十六进制转换为字符串(北欧)
Data received from BLE unable to convert from hex to string (Nordic)
在 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 中输入 as "%X" 时,值不会转换为字符串,因为 buf2/buf3 字符串不会打印任何内容。当前代码
sprintf(buf2, "%s", ((char*)p_evt_write->data[n]));
returns 错误 'error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]'。如果我删除了 (char*) 类型转换,它 returns 错误 'error: format '%s' 期望类型为 'char *'' 的参数。
我看到 p_evt_write->data[n] 数据声明为
uint8_t data[1];
我目前正在使用 Nordic 的 nRF51DK 与 Eclipse IDE 和 SEGGER RTT JLink 进行调试。所有打印都打印到 SEGGER RTT。 (printf不行,用SEGGER_RTT_printf代替打印)
如何成功地将所有十六进制值连接在一起形成一个字符串?谢谢。
要附加到缓冲区,您可以使用以下命令:
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 结尾的字符串,请分配足够的 space,复制字节并附加一个 NUL。
char* s = malloc(total_len + 1);
memcpy(s, buf, total_len);
s[total_len] = 0;
当然,如果 buf
的任何元素是 NUL (0
),您将看到一个被截断的字符串。没有办法解决这个问题(不删除 NUL)。
请注意 ->data
不包含 "hex values"。十六进制是数字的文本表示。你没有十六进制;你有数字。这很好,因为这意味着不需要转换。您只需要复制字节并添加一个 NUL。
请注意,您遇到的特定错误是因为您将 uint8_t
(数字)转换为 char*
(指针)。这是没有意义的。您可能想要 (char*)(&(p_evt_write->data[n]))
,但这也行不通,因为 %s
不只是期望指向字符的指针,而是指向以 NUL 字符结尾的序列的第一个字符的指针。
假设您想要获取您收到的数据的十六进制表示形式的字符串,请尝试这样的操作...
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);
在 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 中输入 as "%X" 时,值不会转换为字符串,因为 buf2/buf3 字符串不会打印任何内容。当前代码
sprintf(buf2, "%s", ((char*)p_evt_write->data[n]));
returns 错误 'error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]'。如果我删除了 (char*) 类型转换,它 returns 错误 'error: format '%s' 期望类型为 'char *'' 的参数。
我看到 p_evt_write->data[n] 数据声明为
uint8_t data[1];
我目前正在使用 Nordic 的 nRF51DK 与 Eclipse IDE 和 SEGGER RTT JLink 进行调试。所有打印都打印到 SEGGER RTT。 (printf不行,用SEGGER_RTT_printf代替打印)
如何成功地将所有十六进制值连接在一起形成一个字符串?谢谢。
要附加到缓冲区,您可以使用以下命令:
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 结尾的字符串,请分配足够的 space,复制字节并附加一个 NUL。
char* s = malloc(total_len + 1);
memcpy(s, buf, total_len);
s[total_len] = 0;
当然,如果 buf
的任何元素是 NUL (0
),您将看到一个被截断的字符串。没有办法解决这个问题(不删除 NUL)。
请注意 ->data
不包含 "hex values"。十六进制是数字的文本表示。你没有十六进制;你有数字。这很好,因为这意味着不需要转换。您只需要复制字节并添加一个 NUL。
请注意,您遇到的特定错误是因为您将 uint8_t
(数字)转换为 char*
(指针)。这是没有意义的。您可能想要 (char*)(&(p_evt_write->data[n]))
,但这也行不通,因为 %s
不只是期望指向字符的指针,而是指向以 NUL 字符结尾的序列的第一个字符的指针。
假设您想要获取您收到的数据的十六进制表示形式的字符串,请尝试这样的操作...
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);