如何替换结构体数组中的每个值

时间:2019-04-12 17:11:46

标签: c arduino

我正在尝试替换struct数组中的每个值,似乎代码可以工作,但是结果是struct数组中的所有元素都更改为相同,请帮忙。

typedef struct { 
    char* name;
    char* mac;
} objThing;

objThing arrayThings[] {
    {"a", ""},
    {"b", ""},
    {"c", ""}
};

void updateMAC()
{
    for (uint8_t t = 0; t < sizeof(arrayThings)/sizeof(objThing); t++)
    {
        char* name = arrayThings[t].name;
        char* mac = arrayThings[t].mac;
        char* new_mac = string2char(MAC_ADDRESS);
        char* new_thing = CombineChars(name, new_mac);
        arrayThings[t].thing = new_thing;
    }
}

char* CombineChars(char* str1, char* str2)
{
    static char strOut[256];
    if((strlen(str1) + strlen(str2)) < 256)
    sprintf(strOut, "%s-%s", str1, str2);
    return strOut;
}

我希望输出是:

"a", "a-xxxxxxxxxxxx",
"b", "b-xxxxxxxxxxxx",
"c", "c-xxxxxxxxxxxx"

但实际输出是:

"c", "c-xxxxxxxxxxxx",
"c", "c-xxxxxxxxxxxx",
"c", "c-xxxxxxxxxxxx"

2 个答案:

答案 0 :(得分:0)

您正在返回指向static变量的指针。这使得每个arrayThings[t].mac都指向它。一些修复。

使用new(默认情况下,Arduino IDE使用C ++。如果使用的是C,请使用malloc()):

char* CombineChars(char* str1, char* str2)
{
    char *strOut = new char[strlen(str1) + strlen(str2) + 2];
    ....

请不要忘记delete(或free())。但是,在Arduino上频繁调用new可能会使堆碎片化,因此应谨慎使用。

另一个选择是使您的结构具有数组。这完全避免了new/delete

typedef struct { 
    char name[256];
    char mac[256];
} objThing;

bool CombineChars(char *str1, char *str2, char *dest, size_t dest_size)
{
    // Ok to be static. Just a temp buffer
    static char strOut[256];
    size_t required_space = strlen(str1) + strlen(str2) + 2;
    if (required_space <= sizeof(strOut) && required_space <= dest_size) {
        sprintf(strOut, "%s-%s", str1, str2);
        strcpy(dest, strOut);
        return true;
    }
    return false;
}

或者仅使用Arduino Strings

typedef struct { 
    String name;
    String mac;
} objThing;


String separator = "-";
for (uint8_t t = 0; t < sizeof(arrayThings)/sizeof(objThing); t++)
{
    char* new_mac = string2char(MAC_ADDRESS);
    arrayThings[t].mac = arrayThings[t].name + separator + new_mac;
}

答案 1 :(得分:0)

在基本的Arduino上(例如,带有2kB RAM的Uno),您应该小心使用String对象和new运算符。为每个文本提供256字节也不是解决方案。

MAC地址具有固定大小(6个字节,不是随机长度的文本)。对于名称,您应该将项目限制为合理的文本长度,并在编译时直接提供该内存。

并且,如果可能的话,应该避免在运行时更改文本(尤其是放大文本)。我看不到您的CombineChars()函数的好处。 (您可能有一个打印助手,在需要时会产生这样的输出)