如何将 const char * 数组项添加到 const char * 字符串?

Posted

技术标签:

【中文标题】如何将 const char * 数组项添加到 const char * 字符串?【英文标题】:How do I add a const char * array item to a const char * string? 【发布时间】:2021-08-12 23:34:43 【问题描述】:

我正在使用 ImGui 并尝试向我的 const char * 添加一个数组项,以便我可以显示所选的项。我该怎么做?它显示的是随机字母,而不是我想要的。

static const char* FruitsList[] =  "Mango", "Apple", "Pear", "Bannana";
indexFruit = 2;
const char * chosenFruitText = "Chosen Fruit"  + char(FruitsList[indexFruit]);
ImGui::ListBox(chosenFruitText , &indexFruit , FruitsList, IM_ARRAYSIZE(FruitsList));

【问题讨论】:

你不能。 const 表示您无法更改它。您可以为自己分配一个足够大且可写的新数组,并将两个字符串写入其中,但这是为疯子和受虐狂准备的。请改用std::string。使用std::string::c_strstd::string 中获取const char * 以供调用ListBox 使用。 您正在尝试将两个 const char* 添加到彼此,这在 C++ 中无效。添加的至少一侧必须是通过此运算符支持字符串连接的东西。喜欢std::string。你需要一个体面的语言介绍性文字。 健全性检查:我认为,因为 ImGui (顾名思义)是即时的,所以字符串很快就会被销毁并不重要。一般来说,您需要非常小心.c_str() 的结果不会超过它来自的对象。 const char * chosenFruitText = "Chosen Fruit" + char(FruitsList[indexFruit]); 是偷偷摸摸的。 "Chosen Fruit"constchar 数组。 char(FruitsList[indexFruit]) 获取地址FruitsList[indexFruit] 并将其转换为char,丢弃大部分地址。你得到的是一个随机的角色。将char 添加到数组中不会附加字符,它会获取字符的数值并像数组中的索引一样使用,执行指针运算。这使得chosenFruitText 指向"Chosen Fruit" 开始之后的某个地方。 这都是合法的 C++ 语法,所以它可以编译,甚至可能不会给你太多的编译器警告。您可能会得到一个警告,警告 char(FruitsList[indexFruit]) 会丢失将地址缩减为一个字节的精度。 【参考方案1】:

您不能将 char/const char* 附加到 const char[](您的字符串文字)。但是您可以连接 std::string 和字符串文字,例如:

static const std::string FruitsList[] =  "Mango", "Apple", "Pear", "Bannana";
indexFruit = 2;
std::string chosenFruitText = "Chosen Fruit" + FruitsList[indexFruit];
ImGui::ListBox(chosenFruitText.c_str(), &indexFruit, FruitsList, IM_ARRAYSIZE(FruitsList));

否则,您将不得不做更多类似的事情:

static const char* FruitsList[] =  "Mango", "Apple", "Pear", "Bannana";
indexFruit = 2;
char chosenFruitText[22] = "Chosen Fruit: ";
strcpy(chosenFruitText+14, FruitsList[indexFruit]);
ImGui::ListBox(chosenFruitText, &indexFruit, FruitsList, IM_ARRAYSIZE(FruitsList));

【讨论】:

【参考方案2】:

C 编程语言中没有字符串操作,不像您的代码所暗示的那样。在表达式“const char* ChosenFruit = ...”中,您告诉编译器您想要将包含“Chosen Fruit”的数组的地址与 FruitsList 中第三个字符串的地址(您将其截断为'char' 因为类型转换),并将结果分配给 ChosenFruit。 ChosenFruit 只是指向内存中很可能不包含可打印字符的某个遥远位置。

要在 C 中连接两个字符串,您必须分配一个足够大的新数组来保存结果,并显式复制两个字符串的字符。您可以使用 'strcpy()' 和 'strcat()' 函数进行复制:

const char* s1 = "Hello ";
const char* s2 = "world!";
char s3[32]; /* big enough to hold s1 and s2 */
strcpy( s3, s1 ); /* copy s1 to s3 */
strcat( s3, s2 ); /* copy s1 to end of s3 */

您可以在 C++ 中执行相同的操作,但使用 C++ 标准库中的“std::string”对象可以说是更安全和更好的做法。 'std::string' 对象自动分配从堆中保存字符串所需的内存量,在不再需要时自动释放此内存,并实现一个版本的 '+' 运算符来满足您的需求(串联):

#include <string>

static const std::string Fruits[] =  "Mango", "Apple", "Pear", "Banana" ;
static const std::string Prefix = "Chosen Fruit ";
std::string ChosenFruit = Prefix + Fruits[index];

表达式“ChosenFruit = Prefix + ...”的意思是“调用以两个 'std::string' 对象作为参数的 '+' 运算符版本”。这个“+”运算符连接两个字符串并返回一个包含结果的新“std::string”对象。

【讨论】:

以上是关于如何将 const char * 数组项添加到 const char * 字符串?的主要内容,如果未能解决你的问题,请参考以下文章

C++ 将字符串添加到 const char* 数组

如何将char赋给const char *

C/C++ 将 char 数组初始化为 const char*

从 const char* 复制到字节数组 C++/c# interop Marshal::Copy

将 Swift 字符串数组转换为 const char * const *

VS2017,不能将const char *转为char *