c - 动态字符数组大小调整

标签 c arrays embedded

在我的应用程序中,我定义了一个 char 数组,它可以采用以下三个选项之一:“okay”、“high”、“low”,然后通过串行端口将其发送到远程设备。我目前的数组大小可以容纳 4 个字符的单词加上回车符和换行符,但是当我必须发送“low”时,我在字符串中得到一个空字符,我担心这会混淆主机终端。

数组定义

char mod1_status_char[6] = {'0','0','0','0','0','0'};     
char mod2_status_char[6] = {'0','0','0','0','0','0'};     
char mod3_status_char[6] = {'0','0','0','0','0','0'};     

switch case 语句示例:

void DCOKStatus(uint8_t *ptr_status)
{
    uint8_t status = *ptr_status;

    switch (status) 
    {
        case 0x00:
            strcpy(mod1_status_char, "okay");
            strcpy(mod2_status_char, "okay");
            strcpy(mod3_status_char, "okay");
            break; 
        case 0x10:
            strcpy(mod1_status_char, "okay");
            strcpy(mod2_status_char, "okay");
            strcpy(mod3_status_char, "low");
            break;
     }

这是使消息字符串发送的结构

    strcpy(MsgStatus_on.descriptor_msg, "$psu_");
    MsgStatus_on.address01 = hex_addr[0];
    MsgStatus_on.address02 = hex_addr[1];
    MsgStatus_on.space01 = 0x20;
    strcpy(MsgStatus_on.cmdmsg01, "op_en op1_");
    strcpy(MsgStatus_on.statusmsg01, mod1_status_char);
    MsgStatus_on.space02 = 0x20;
    strcpy(MsgStatus_on.cmdmsg02, "op2_");
    strcpy(MsgStatus_on.statusmsg02, mod2_status_char);
    MsgStatus_on.space03 = 0x20;
    strcpy(MsgStatus_on.cmdmsg03, "op3_");
    strcpy(MsgStatus_on.statusmsg03, mod3_status_char);
    MsgStatus_on.CR = 0x0D;
    MsgStatus_on.LF = 0x0A;

这会发送消息

void USARTWrite(char *object, uint32_t size)
{    
    GPIO_SetBits(GPIOB, GPIO_Pin_1);

    char *byte;
    for (byte = object; size--; ++byte)                                                                       
    {                                       
          USART_SendData(USART1,*byte);                                 

    }

当我需要发送“低”时,有人能建议一种动态调整数组大小以缩短一个字符的好方法吗?

谢谢

最佳答案

我认为不需要动态大小的数组。在 C 语言中有两种动态调整数组大小的方法:使用 malloc 或类似方法分配它;或使用 C99 VLA。但是在这种情况下,你有不同长度的字符串,当然重要的一点是以正确的顺序写入正确的字节?我个人更喜欢这样的东西,也许:

char * strings[] = {"okay\r\n", "high\r\n", "low\r\n"};

serial_send(strings[msg_number], strlen(strings[msg_number]));

您不一定非要调用 strlen,您可以将长度存储在另一个数组中。但即使在最小的嵌入式设备上,与发送串行数据相比,数到 6 也只需要很少的时间。

当然,我假设无论您调用什么函数来实际发送数据,都需要一个指针和一个长度。但如果没有,我也看不到动态大小的数组有何帮助。

我认为这里很难回答问题的一般问题是,您没有真正说明数组的“大小”是多少,或者为什么它与实际写入的字节数有任何关系到串口。

编辑:通过您的额外解释,关键似乎是三个单独的字符串被“传入”的结构。不确定将字符串传递到结构中意味着什么。如果它当前看起来像这样:

struct serialmessage {
    char first[6];
    char second[6];
    char third[6];
};

serialmessage msg;
memcpy(msg.first, mod1_status_char, 6); // etc.

那么也许这样做会更好:

char *char mod1_status_char; // etc.

switch(status) {
    case 0x00:
        mod1_status_char = strings[0]; // or #define STATUS_OK 0
        mod2_status_char = strings[0];
        mod3_status_char = strings[0];
        break;
    case 0x10:
        mod1_status_char = strings[0];
        mod2_status_char = strings[0];
        mod3_status_char = strings[2]; // STATUS_LOW
};

serialmessage msg[3*MAX_STRING_LENGTH+1];
strcpy(msg, mod1_status_char); // or use stpcpy if you have it
strcat(msg, mod2_status_char);
strcat(msg, mod3_status_char);

然后使用 strlen(msg) 发送结构。 msg 在这里并不完全是“动态的”,但其中字符串的长度根据数据而变化,这可能是您想要的。或者我对这三个 char 数组的作用仍然有误解。

在我看来,过多地复制字符串只会带来复杂性。通过指针引用它们,直到最后一刻,当您的消息被组装时,您将代码中必须获得正确缓冲区大小的地方的数量减到最少。

关于c - 动态字符数组大小调整,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2206691/

相关文章:

java - 将对象添加到数组的方法

c - 如何测试 strdup() 是否可用?

c - 我只是想不通 strcat

java - 将数组值传递给单独的方法

c - 在 C 中使用 malloc 保留内存

c - AVR RTOS 的内联 C 汇编器宏

c - 需要将我的固件镜像迁移到 ROM 掩码

c - 在 STM32H7 上使用执行跟踪片上缓冲区 (ETB)

c - eclipse C 编译器无法识别//行注释

c - 为什么在这种情况下 ptr + 1 与++ptr 不同?