c 中 uint8_t 的字符串赋值

String assignment to uint8_t in c

我试图在 IAR 中将字符串分配给 uint8_t 缓冲区,但我收到一条警告消息。

rx_buffer.rx_struct.RESP.RESPONDuint8_t 类型的 struct field

我的代码是:

strncpy(rx_buffer.rx_struct.RESP.RESPOND, (uint8_t *)'NS,', 3);

相关的警告消息如下:

Warning[Pe1422]: multicharacter character literal (potential portability problem) 
Warning[Pe167]: argument of type "uint8_t *" is incompatible with parameter of type "char *",
Warning[Pe167]: argument of type "uint8_t *" is incompatible with parameter of type "char const"

我已经写了一个解决方法:

rx_buffer.rx_struct.RESP.RESPOND[0] = 'N';
rx_buffer.rx_struct.RESP.RESPOND[1] = 'S';
rx_buffer.rx_struct.RESP.RESPOND[2] = ',';

但我并不满意。正确的做法是什么?

strncpy 期望它的前两个参数分别是 char *const char * 类型。如果有的话,您应该转换为 char *,而不是转换为 unit8_t *

此外,'NS,' 是字符文字,字符串文字是 "NS,"

您的代码在很多方面都不正确:

strncpy(rx_buffer.rx_struct.RESP.RESPOND, (uint8_t *)'NS,',3);
  • 目标数组没有类型char *
  • 源不是一个数组:'NS,' 是一个多字符字符常量,一个不可移植的历史古怪,没有人会在任何体面的代码中使用...将它转换为 (uint8_t *) 没有修复这个问题。您应该只使用双引号:"NS,".
  • strncpy() 不是这项工作的合适工具。事实上,它从来都不是适合任何工作的工具。这个函数不是 strcpy 的安全替代品,它的语义被广泛误解,很容易出错。您应该避免使用此功能。在这种特殊情况下,它只会按预期复制 3 个字节,但为什么在 memcpy() 是更简单的解决方案时使用 strncpy()

您可以通过以下方式实现您的目标:

memcpy(rx_buffer.rx_struct.RESP.RESPOND, "NS,", 3);

或者按照问题中的说明分别分配每个字节。两种方法都可能产生相同的机器代码。

您使用的是单引号,但需要双引号 ("NS,") ,并查看 Stop using strncpy already!,在这种情况下它应该按预期工作,因为您不希望尾随'[=12=]',但不要使用它。

使用 memcpymemmove,另外(作为风格问题)不要使用像 3:

这样的幻数
#include <stdio.h>
#include <string.h>
#include <stdint.h>

#define MAX_SIZE 3

int main(void)
{
    uint8_t arr[MAX_SIZE];

    memmove(arr, "NS,", MAX_SIZE);
    for (int i = 0; i < MAX_SIZE; i++) {
        printf("%c", arr[i]);
    }
    printf("\n");
    return 0;
}