0

我有这个代码:

std::string name = "kingfisher";
char node_name[name.size()+1];
strcpy(node_name,name.c_str());
node_name[name.size()] = '\0';

它在 DevC++ 中运行良好,但在 Visual C++ 中,我遇到了一个名为“name.size() 必须是常量值”的问题!如何解决问题?我知道我必须在声明中使用 const 值node_name,但有时(如上面的情况)我不能!谢谢!

4

5 回答 5

4
char node_name[name.size()+1];

由于name.size()在编译时不知道 的值,因此在上述声明中,node_name是可变长度数组 (VLA),这在 ISO C++ 中是不允许的。

在 DevC++ 中,它可以编译并工作,因为它提供 VLA 功能作为扩展,在您的编译配置中启用。

使用std::string,或char *new[]/delete[]任何适合您需要的东西一起使用。

在您的特定情况下,即如果您已经知道字符串文字,那么您可以这样写:

char node_name[] = "kingfisher"; //this works great!

但是,如果字符串值未知并且您想从某处复制它,请执行以下操作:

char *node_name = new char[name.size()+1];
std::strncpy(node_name, name.c_str(), name.size()+1); //use strncpy

//work with node_name

//must deallocate the memory
 delete []node_name; //not `delete node_name;`

使用std::strncpy代替std::strcpy,因为前者将缓冲区大小也作为第三个参数,如上所示,而后者则没有(这通常是不安全的;但在这种情况下不是)。

于 2012-06-14T05:04:36.940 回答
3

可变长度数组不是标准 C++ 的一部分。您需要在编译时给出大小。name.size()将在运行时发生。注释应该足以解释幻数或常数。

char node_name[11]; //length of "kingfisher" + null

如果您在编译时不知道字符串的长度(但在您的示例中知道),您可以使用动态数组,正如 Nawaz 的回答中很好解释的那样。

于 2012-06-14T05:04:27.800 回答
2

有很多选择:

std::string name = "kingfisher";
char* node_name = alloca(name.size() + 1);
strcpy(node_name, name.c_str());
// no need to explicitly set the '\0' - strcpy copies it too
...OR...
char* node_name = new char[name.size() + 1];
strcpy(node_name, name.c_str());
...OR...
char* node_name = strdup(name.c_str());  // allocate on malloc/free/realloc "C" heap
...OR...
std::vector<char> node_name(name.data(), name.data() + name.size()); // sans '\0'
...OR...
std::vector<char> node_name(name.c_str(), name.c_str() + name.size() + 1); // with '\0'
...OR...
std::string node_name = node;  // do something with node_name.c_str() / .data() etc.

注意:尽管 Ernest 对 Stefan 的已删除答案发表了“不要在 C++ 中使用 malloc(),使用 new[]”的评论,但它可能是必要的 - 例如,当传递指向可能重新分配或释放内存的 C 代码的指针时。

于 2012-06-14T05:19:57.207 回答
0

大小在运行时确定的数组称为变长数组VLA。VLA 是 C99 中的一个特性。一些 C++ 编译器支持它们作为扩展,而一些不支持;听起来你的 Visual C++ 版本没有。

node_name您始终可以使用 动态分配new,而不是在堆栈上。

于 2012-06-14T05:05:42.117 回答
0

我的第一种方法是查看您使用数组的目的,并询问是否有更好的方法。

如果你真的需要这个数组,我会建议一个向量:它是动态大小的,但不需要删除。

    std::string name = "kingfisher";
    std::vector<char> name_buff(name.begin(), name.end());
    name_buff.push_back(0);  // nul-terminate
    char *node_name = &name_buff[0];
    // ...
于 2012-06-14T08:30:40.490 回答