包含 char 数组的结构
A struct that contains an array of char arrays
我正在尝试定义一个结构的实例,但在设置这个变量时遇到了特别的麻烦。这是一个字符数组数组。
这是我的头文件中的结构...
struct widget_t {
char *name;
uint8_t numberOfNicknames;
char *nicknames[];
};
这是我尝试设置 widget_t
结构的实例...
widget_t SomeWidget;
void setUpFunction () {
SomeWidget.name = (char *)"Lawn Mower";
SomeWidget.numberOfNicknames = 2;
SomeWidget.nicknames = {
"Choppie McGrasschopper",
"Really Noisy"
};
}
因此,当我尝试将昵称放入 SomeWidget.nicknames
时发生错误。我不确定我是否需要做一些时髦的事情,就像我用 name
作为指针所做的那样......?
棘手的一点是 nicknames
的数量是可变的。所以每个实例都会想要设置不同数量的它们。
您想要做的是将字符串文字分配给 char *
指针——这很糟糕(请参阅 How to get rid of deprecated conversion from string constant to ‘char*’
warnings in GCC? 了解更多信息)。这是一种可能的方法:
#define MAX_NAME_LEN 128
#define MAX_NICK_NAMES 10
struct widget_t {
char name[MAX_NAME_LEN];
uint8_t numberOfNicknames;
char nicknames[MAX_NICK_NAMES][MAX_NAME_LEN];
};
widget_t SomeWidget;
void setUpFunction () {
strcpy(SomeWidget.name, "Lawn Mower");
SomeWidget.numberOfNicknames = 2;
strcpy(SomeWidget.nicknames[0], "Choppie McGrasschopper");
strcpy(SomeWidget.nicknames[1], "Really Noisy");
}
无论如何,既然你用 C++
标记了你的问题,我建议你改用 std::string
和 std::vector
。
你遇到的问题是 c++ 不支持变量数组。相反,您将不得不使用 new 动态分配内存,或者在您的情况下 new[].
首先,您需要将数据类型更改为 char**
,几乎与之前的相同。然后你可以像这样分配任意数量的字符串 nicknames = new char*[number_of_nicknames]
.
重要的是,使用此方法,您必须像这样手动删除昵称:delete[] nicknames;
。实现此目的的最佳方法是使用 RAII(在解构函数中删除昵称)
当您有动态字符串时,您将使用以下结构
struct widget_t {
// optional constructor to allocate nicknames
~widget_t()
{
for (int i = 0; i < numberOfNicknames; ++i)
{
char* nickname = nicknames[i];
if (nickname)
delete[] nickname;
}
delete[] nicknames;
}
char *name;
uint8_t numberOfNicknames;
char **nicknames = NULL;
};
下一个
和常量字符串
struct widget_t {
// optional constructor to allocate nicknames
// allocate nicknames like
// -> nicknames = new const char*[numberOfNicknames];
~widget_t()
{
if (nicknames) delete[] nicknames;
}
char *name;
uint8_t numberOfNicknames;
const char **nicknames = NULL;
};
一个选项是:
struct widget_t {
char const *name;
uint8_t numberOfNicknames;
char const * const *nicknames;
};
static char const *mower_nicknames[] = { "Choppie", "Bob" };
widget_t SomeWidget = { "Lawn Mower", 2, mower_nicknames };
static char const *bus_nicknames[] = { "Wheels", "Go", "Round" };
widget_t OtherWidget = { "Bus", 3, bus_nicknames };
// no setup function needed
这里有不同的问题。
首先是不完整类型的最后一个成员,因为它是一个未声明维度的数组。这在 C++ 中是不允许的,但大多数编译器允许它作为与 C 具有相同语义的扩展。无论如何,这使用起来相当棘手,因为它只能与分配的结构一起使用,在那里你为结构本身分配内存 和不完整的数组。
接下来,您将尝试分配 给一个数组。你不能。数组不是 C++(也不是 C)中的第一个 class 对象。可以将一个数组作为一个整体进行初始化,但只能对一个数组元素进行赋值。
最后,您将 C 语言字符串分配给 char *
。这很糟糕,因为标准声明垃圾字符串是 const
所以稍后使用指针更改 char 将是未定义的行为。如果您不这样做,它将起作用,但指针至少应声明为 const
.
以下是您如何使用所有这些:
widget_t* setUpFunction () {
// allocates a widget_t with 2 slots in nicknames
widget_t *someWidget = (widget_t *) malloc(sizeof(widget_t) + 2 * sizeof(char *));
someWidget.name = (char *)"Lawn Mower"; // VERY DANGEROUS: pointer should be const
someWidget.numberOfNicknames = 2;
someWidget.nicknames[0] = (char *) "Choppie McGrasschopper"; // SAME DANGER
someWidget.nicknames[1] = (char *) "Really Noisy" // Still same danger
return widget_t;
}
但是所有这些都是 C 风格的,应该在 C++ 中避免。此外,它仍然需要分配内存,这可能不是您想要的 Arduino
我正在尝试定义一个结构的实例,但在设置这个变量时遇到了特别的麻烦。这是一个字符数组数组。
这是我的头文件中的结构...
struct widget_t {
char *name;
uint8_t numberOfNicknames;
char *nicknames[];
};
这是我尝试设置 widget_t
结构的实例...
widget_t SomeWidget;
void setUpFunction () {
SomeWidget.name = (char *)"Lawn Mower";
SomeWidget.numberOfNicknames = 2;
SomeWidget.nicknames = {
"Choppie McGrasschopper",
"Really Noisy"
};
}
因此,当我尝试将昵称放入 SomeWidget.nicknames
时发生错误。我不确定我是否需要做一些时髦的事情,就像我用 name
作为指针所做的那样......?
棘手的一点是 nicknames
的数量是可变的。所以每个实例都会想要设置不同数量的它们。
您想要做的是将字符串文字分配给 char *
指针——这很糟糕(请参阅 How to get rid of deprecated conversion from string constant to ‘char*’
warnings in GCC? 了解更多信息)。这是一种可能的方法:
#define MAX_NAME_LEN 128
#define MAX_NICK_NAMES 10
struct widget_t {
char name[MAX_NAME_LEN];
uint8_t numberOfNicknames;
char nicknames[MAX_NICK_NAMES][MAX_NAME_LEN];
};
widget_t SomeWidget;
void setUpFunction () {
strcpy(SomeWidget.name, "Lawn Mower");
SomeWidget.numberOfNicknames = 2;
strcpy(SomeWidget.nicknames[0], "Choppie McGrasschopper");
strcpy(SomeWidget.nicknames[1], "Really Noisy");
}
无论如何,既然你用 C++
标记了你的问题,我建议你改用 std::string
和 std::vector
。
你遇到的问题是 c++ 不支持变量数组。相反,您将不得不使用 new 动态分配内存,或者在您的情况下 new[].
首先,您需要将数据类型更改为 char**
,几乎与之前的相同。然后你可以像这样分配任意数量的字符串 nicknames = new char*[number_of_nicknames]
.
重要的是,使用此方法,您必须像这样手动删除昵称:delete[] nicknames;
。实现此目的的最佳方法是使用 RAII(在解构函数中删除昵称)
当您有动态字符串时,您将使用以下结构
struct widget_t {
// optional constructor to allocate nicknames
~widget_t()
{
for (int i = 0; i < numberOfNicknames; ++i)
{
char* nickname = nicknames[i];
if (nickname)
delete[] nickname;
}
delete[] nicknames;
}
char *name;
uint8_t numberOfNicknames;
char **nicknames = NULL;
};
下一个
和常量字符串struct widget_t {
// optional constructor to allocate nicknames
// allocate nicknames like
// -> nicknames = new const char*[numberOfNicknames];
~widget_t()
{
if (nicknames) delete[] nicknames;
}
char *name;
uint8_t numberOfNicknames;
const char **nicknames = NULL;
};
一个选项是:
struct widget_t {
char const *name;
uint8_t numberOfNicknames;
char const * const *nicknames;
};
static char const *mower_nicknames[] = { "Choppie", "Bob" };
widget_t SomeWidget = { "Lawn Mower", 2, mower_nicknames };
static char const *bus_nicknames[] = { "Wheels", "Go", "Round" };
widget_t OtherWidget = { "Bus", 3, bus_nicknames };
// no setup function needed
这里有不同的问题。
首先是不完整类型的最后一个成员,因为它是一个未声明维度的数组。这在 C++ 中是不允许的,但大多数编译器允许它作为与 C 具有相同语义的扩展。无论如何,这使用起来相当棘手,因为它只能与分配的结构一起使用,在那里你为结构本身分配内存 和不完整的数组。
接下来,您将尝试分配 给一个数组。你不能。数组不是 C++(也不是 C)中的第一个 class 对象。可以将一个数组作为一个整体进行初始化,但只能对一个数组元素进行赋值。
最后,您将 C 语言字符串分配给 char *
。这很糟糕,因为标准声明垃圾字符串是 const
所以稍后使用指针更改 char 将是未定义的行为。如果您不这样做,它将起作用,但指针至少应声明为 const
.
以下是您如何使用所有这些:
widget_t* setUpFunction () {
// allocates a widget_t with 2 slots in nicknames
widget_t *someWidget = (widget_t *) malloc(sizeof(widget_t) + 2 * sizeof(char *));
someWidget.name = (char *)"Lawn Mower"; // VERY DANGEROUS: pointer should be const
someWidget.numberOfNicknames = 2;
someWidget.nicknames[0] = (char *) "Choppie McGrasschopper"; // SAME DANGER
someWidget.nicknames[1] = (char *) "Really Noisy" // Still same danger
return widget_t;
}
但是所有这些都是 C 风格的,应该在 C++ 中避免。此外,它仍然需要分配内存,这可能不是您想要的 Arduino