使用C ++初始化Struct的变量const char * const *


Initializing a Struct's variable const char* const* with C++

我正在尝试解决一个编码问题,该问题需要使用给定的结构返回结果。 结构定义为:

1
2
3
4
5
6
struct Answer
{
    const char* const* lastNames;
    unsigned numberOfPeople;

}

lastNames是指向姓氏的指针,每个姓氏都由非alpha字符终止。 我似乎无法找到任何方法来转换我用来将所有姓氏编译成我可以分配给lastNames的变量的字符串向量。 我尝试使用所有姓氏创建一个字符串,并使用c_str()分配它,如下所示:
Ans->lastName = allNames.c_str();但这给了我一个错误。 由于问题的局限性,我无法将struct变量更改为其他任何内容。 如何将字符串赋给const char * const *


正在使用的结构有效地使用C风格的方法来定义一个可变大小的指向char的指针数组(其上有const)。您需要存储char const*数组以及指向的实体。以下是如何从std::vector构建它:

1
2
3
4
5
6
7
std::vector<std::string> strings = somehow_compute_the_strings();
std::vector<char const*> array;
for (std::string const& s: strings) {
    array.push_back(s.c_str());
}

Answer answer = { array.data(), array.size() };

当然,如果没有指针指向过时的数据,你就不能返回answer:你需要让两个std::vector保持活着。可能这两个对象可以成为调用该函数的对象的成员。要实际返回answer类型的对象而没有占据std::vector的位置,您可以分配相关实体并接受结果将产生内存泄漏,除非调用者可以清除结果。


你不能只是投东西。 struct Answer需要一个char **,因此只要使用struct Answer,你就必须构建它并使其保持有效。至少他们很友善地让我们知道他们不打算修改它或搞乱清理内存,因为它需要"const char * const *"。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <iostream>
#include <vector>
#include <string>
#include

typedef std::vector<std::string> VectorOfStrings_type;

struct Answer
{
    const char* const* lastNames;
    unsigned numberOfPeople;
};

class AnswerWrapper
{
private:
    // construct and maintain memory so the pointers in the Answer struct will be valid
    char ** lastNames;
    unsigned int numberOfPeople;

public:
    AnswerWrapper(const VectorOfStrings_type &input){
        numberOfPeople = input.size();

        // create the array of pointers
        lastNames = static_cast<char**>(
            malloc(numberOfPeople * sizeof(char*))
        );

        // create each string
        for (unsigned int i = 0; i < numberOfPeople; ++i){
            const std::string &name = input[i];

            // allocate space
            lastNames[i] = static_cast<char*>(
                malloc(name.size() + 1)
            );

            // copy string
            strncpy(lastNames[i], name.data(), name.size());

            // add null terminator
            lastNames[i][name.size()] = '\0';
        }
    }

    operator Answer (){
        return Answer{ lastNames, numberOfPeople };
    }

    ~AnswerWrapper(){
        // critcally important, left as an exercise
        assert(0);
    }
};

void SomeFunctionWhichUsesAnswer(Answer a){
    // presumably you have some legacy C code here
    // but here's a quick and easy demo
    for (unsigned int i = 0; i < a.numberOfPeople; ++i)
        std::cout << a.lastNames[i] << std::endl;
}

int main() {
    // Here is your vector of strings
    VectorOfStrings_type myData {"custom formatted data goes here","and more here","and again" };

    // You must construct a buffer for the"Answer" type, which must remain in scope
    AnswerWrapper temp{ myData };

    // AnswerWrapper is currently in scope, so inside this function, the pointers will be valid
    SomeFunctionWhichUsesAnswer(temp);
}

另外,我注意到Answer中的字符串不被称为null终止。这是一个你可以处理的单独问题。


const成员变量只能在构造函数中指定。
如果你可以添加到结构,定义一个构造函数,并使用: lastname(value)语法;或者在声明实例的地方使用struct Answer myVar{value,number};初始化。

另一个 - 丑陋,危险和不赞成的替代方案是演员:(char**) lastname = value;,或者是C ++语法reinterpret_cast(lastname) = value
如果有人教你这些方法,请改变老师。