我目前有一个带有赋值的声明,看起来像这样:
可能有一个非常简单的解决方案,但是我似乎无法弄清楚。我可以找到无数有关如何在C ++中创建字符串数组的示例,但找不到能说明如何使分配分开的示例。
我目前有一个带有赋值的声明,看起来像这样:
static const char *desc[3] = { "apple", "banana", "orange" };
我想做的是将声明和赋值拆分为单独的语句。声明:
static const char *desc[3];
...但是我似乎无法弄清楚如何完成作业。我尝试了以下方法:
desc = { "apple", "banana", "orange" }; // Expression must have a modifiable lvalue. error: assigning to an array from an initializer list
*desc = { "apple", "banana", "orange" }; // Too many initializer values. error: cannot convert '<brace-enclosed initializer list>' to 'const char*' in assignment
desc[3] = { "apple", "banana", "orange" }; // Too many initializer values. error: cannot convert '<brace-enclosed initializer list>' to 'const char*' in assignment
*desc[3] = { "apple", "banana", "orange" }; // Expression must have a modifiable lvalue. error: assignment of read-only location '* desc[3]'
您的第一个示例在堆栈上分配数组,这仅是可能的,因为编译器知道大小(因为所有字符串都是固定长度,并且在声明期间提供)。>>
当您分开声明和初始化时,编译器无法知道要在堆栈上分配多少内存,因此您需要将类型更改为指针(无论指针指向什么,其大小都是固定的):
static const char** desc;
然后使用
new
为数组分配足够的内存:
desc = new const char*[3]{ "apple", "banana", "orange" };
但是这意味着您现在还必须
delete[]
指向desc
指向的数组,否则会发生内存泄漏。
更好的方法是使用现代容器类型,例如std::vector
和std::string
:
static std::vector<std::string> desc;
然后
desc.push_back("apple"); desc.push_back("banana"); desc.push_back("orange");
这些类在后台为您处理所有麻烦的内存管理。
另一种选择,如果您真的想要一个原始数组,并且不想依赖new[]
和delete[]
,则声明一个固定大小的数组,该数组具有足够的空间来容纳您的字符串,如下所示:
static const char desc[3][128];
然后将字符串值复制到该内存块中:
std::strcpy(desc[0], "apple"); std::strcpy(desc[1], "banana"); std::strcpy(desc[2], "orange");
但是我真的不建议您这样做,因为从长远来看,当您添加或删除字符串,或更改其长度等时,您可能会遇到错误,因此冒着风险。>>
我目前有一个带有赋值的声明,看起来像这样:
static const char *desc[3] = { "apple", "banana", "orange" };
这不是“任务”。这是初始化。
我似乎无法弄清楚如何完成作业。
数组不可分配。您无法分配给数组。
如果要在初始化数组后修改数组的元素,则需要迭代每个元素并逐个分配它们:
const char *arr[] = {"apple", "banana", "orange"}; static_assert(std::size(arr) == std::size(desc)); std::copy_n(arr, std::size(arr), desc);
或者您可以将数组包装到一个类中,在这种情况下,将为您生成一个赋值运算符。有一个用于此类数组包装器
std::array
的标准模板:static std::array<const char*, 3> desc; // later desc = {"apple", "banana", "orange"};
Max Vollmer提供了一些极好的建议,尽管在“现代C ++”中不建议使用new
和原始指针(在C ++ 11之后)。参见[1](Sutter是C ++标准委员会的成员,所以他知道他的事。
因此,如果您要使用“真正的C ++方式”以包含字符串数组,那么应该使用:
std::vector<std::string> dest_a; dest_a.push_back("apple"); dest_a.push_back("banana"); // or std::vector<std::string> dest_b(3); dest_b[0] = "orange"; dest_b[1] = "pear"; dest_b[2] = "plumb";
如果您需要
原始指针,我想我会选择旧的Cstrcpy
函数。
尽管,您可能只是在寻找它。
static const char *ptr[2]; ptr[0] = "orange"; ptr[1] = "pear";
您的声明是错误的,因为当您编写char [3]时,它将使您的字符数组包含3个字符,而不是包含3个不同的无限字符的数组。
您的第一次尝试算作分配(您不能使用const进行,而不是初始化。)>
此定义应该起作用:
const char*[] foo::desc = { "apple", "banana", "orange" };
对于这样的声明:
class foo {
const static char*[] desc;
};
我目前有一个带有赋值的声明,看起来像这样:
Max Vollmer提供了一些极好的建议,尽管在“现代C ++”中不建议使用new
和原始指针(在C ++ 11之后)。参见[1](Sutter是C ++标准委员会的成员,所以他知道他的事。
您的声明是错误的,因为当您编写char [3]时,它将使您的字符数组包含3个字符,而不是包含3个不同的无限字符的数组。
您的第一次尝试算作分配(您不能使用const进行,而不是初始化。)>
此定义应该起作用: