如何从字符串常量创建一个字符数组?

How to create a char array from string constant?

我尝试为我的单元测试创​​建一个 char* values[],它将被编写但从常量初始化。天真的方式抛出一个警告,ISO C++ 禁止它:

char* single[1];
single[0] = "foobar";

我尝试了以下显然不起作用的方法:

std::string executable = "foobar";
std::array<char, executable.size()> data; // Error: size not known at compile time
std::copy(executable.begin(), executable.end(); data.data());

char* single[1];
single[0] = data.data();

一定有这样的方法:

std::array<char> data = { "foobar" };
char* single[1];
single[0] = data.data();

这有点长,但似乎可以满足您的需求。这是文件 foo.cpp:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cstdio>

int main(int argc, char* argv[])
{
    std::vector<std::string> strings = {"foobar", "barbaz"};

    char* values[strings.size()];

    for (int i = 0; i < strings.size(); ++i) {
        values[i] = new char[strings[i].size() + 1];
        std::copy(strings[i].cbegin(), strings[i].cend(), values[i]);
        values[strings[i].size()] = '[=10=]';
    }

    for (int i = 0; i < strings.size(); ++i) {
        printf("%s\n", values[i]);
    }

    return 0;
}

然后:

$ make foo
g++     foo.cpp   -o foo
$ ./foo
foobar
barbaz

你当然应该 delete char* 数组的每个元素,并且可以将用于从 std::string 复制到 char* 的循环放在一个函数中等等。

PS:auch,这个解决方案与 this answer 相同,有人已经链接了....链接的其他答案有更多细节。这是否意味着您的问题是重复的?我让有经验的用户决定。

您可以使用 std::vector<std::string> 来存储您的数据,并使用 c_str() of std::string 将您的字符串解析为 char*

std::string foo = "foobar";
std::vector<char> data(foo.data(), foo.data()+foo.size()+1u);
char* single[1];
single[0] = data.data();

How to convert a std::string to const char* or char*?

如果这种模式再次出现,您可以使用某种转换函数:

template<class CharT, std::size_t N>
std::vector<CharT> literal_vector(CharT const (&a)[N])
{
    return std::vector<CharT>(&a[0], (&a[0]) + N);
}

然后

std::vector<char> lv = literal_vector("Hello");
single[0] = lv.data();

我建议您将 to_array 添加到您的工具箱。然后你可以简单地写

auto data = to_array("foobar");
char* single[1];
single[0] = data.data();

这里有两种方法,都是使用memcpy

  1. 使用动态内存。
  2. 使用静态内存。
 

    using namespace std;

    #define MAX_BUFFER_SIZE 250
    int main()
    {
        const char* myData = "This is My Data";

        int sizeOfmydata = std::strlen(myData);;

        //1.- Dinamic Memory
        char* data1 = new char[sizeOfmydata];
        std::memcpy(data1, myData, sizeOfmydata);

        //2.- Static Memory
        char data2[MAX_BUFFER_SIZE];
        memset(data2, '[=10=]', MAX_BUFFER_SIZE);
        std::memcpy(data2, myData, sizeOfmydata);


        delete[] data1;
        return 0;
    }

即使你的问题没有被标记为c++1z,值得一提的是std::stringdata函数的constness限制在当前的工作草案中已经解除标准 (N4618),即将作为 C++17 发布。在 [basic.string] 中,可以同时找到:

const charT* data() const noexcept;
charT* data() noexcept;

您的编译器可能已经支持它,可能需要编译器标志 -std=c++1z 或类似标志。如果是这样,你应该能够写:

std::string executable = "foobar";
char *single[1];
single[0] = executable.data();