簡體   English   中英

在 C++ 中使用字符串數組拆分聲明和賦值

[英]Splitting declaration and assignment with string array in C++

對此可能有一個非常簡單的解決方案,但我似乎無法弄清楚。 我可以找到無數關於如何在 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]'

您的第一個示例在堆棧上分配數組,這僅是可能的,因為編譯器知道大小(因為所有字符串都是固定長度並在聲明期間提供)。

當您將聲明和初始化分開時,您的編譯器無法知道要在堆棧上分配多少 memory,因此您需要將類型更改為指針(無論它指向什么,它都有固定大小):

static const char** desc;

然后使用new為數組分配足夠的 memory :

desc = new const char*[3]{ "apple", "banana", "orange" };

但是,這意味着您現在還必須delete[] desc指向的數組,否則您會得到 memory 泄漏。

更好的是使用現代容器類型,如std::vectorstd::string

static std::vector<std::string> desc;

接着

desc.push_back("apple");
desc.push_back("banana");
desc.push_back("orange");

這些類在后台為您處理所有令人討厭的 memory 管理。


另一種選擇,如果你真的想要一個原始數組,並且不想依賴new[]delete[]是聲明一個固定大小的數組,為你的字符串提供足夠的空間,如下所示:

static const char desc[3][128];

然后將字符串值復制到 memory 的那個塊中:

std::strcpy(desc[0], "apple");
std::strcpy(desc[1], "banana");
std::strcpy(desc[2], "orange");

但是我真的不建議這樣做,因為從長遠來看,當您添加或刪除字符串或更改它們的長度等時,您會冒着錯誤的風險。

我目前有一個看起來像這樣的賦值聲明:

 static const char *desc[3] = { "apple", "banana", "orange" };

這不是“任務”。 這是初始化。

我似乎無法弄清楚如何完成任務。

Arrays 不可分配。 您不能分配給數組。

如果要在初始化后修改數組的元素,則需要迭代每個元素並一一分配:

const char *arr[] = {"apple", "banana", "orange"};
static_assert(std::size(arr) == std::size(desc));
std::copy_n(arr, std::size(arr), desc);

或者您可以將數組包裝到 class 中,在這種情況下,將為您生成一個賦值運算符。 這種數組包裝器std::array有一個標准模板:

static std::array<const char*, 3> desc;
// later
desc = {"apple", "banana", "orange"};

Max Vollmer 給出了一些很好的建議,盡管在“現代 C++”(C++11 后)中不鼓勵使用new指針和原始指針。 見[1](薩特是C++標准委員會的成員,所以他知道他的事情。

因此,如果您要使用“真正的 C++ 方式”來擁有一個字符串數組,那么您應該使用 go :

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";

如果您需要原始指針,我想我會為舊的 C strcpy函數使用 go 。


雖然,你可能只是在尋找這個。

  static const char *ptr[2];
  ptr[0] = "orange";
  ptr[1] = "pear";

[1] https://herbsutter.com/elements-of-modern-c-style/

你的第一次嘗試算作賦值(你不能用數組做),而不是初始化。

這個定義應該有效:

const char* foo::desc[] = { "apple", "banana", "orange" };

對於如下所示的聲明:

class foo {
    static const char* desc[];
};

您的聲明是錯誤的,因為當您編寫 char [3] 時,它將使您的字符數組包含 3 個字符,而不是包含 3 個不同的無限字符的數組。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM