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

时间:2018-11-26 02:07:06

标签: c++

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

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

}

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

3 个答案:

答案 0 :(得分:2)

有效使用的结构使用C样式的方法来定义指向char的指针的可变大小的数组(上面撒有const)。您需要同时存储char const*数组和指向的实体。您可以通过以下方法从std::vector<std::string>构建它:

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的位置,您可以分配相关实体并接受结果将产生内存泄漏,除非调用者可以清除结果

答案 1 :(得分:1)

您不能只投东西。 struct Answer期望使用char **,因此只要使用struct Answer,就必须构建它并使其保持有效。至少他们很友好,让我们知道他们不打算修改它或清理内存,因为它需要“ const char * const *”。

#include <iostream>
#include <vector>
#include <string>
#include <assert.h>

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终止。这是一个单独的问题,您可以解决。

答案 2 :(得分:0)

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

另一个-丑陋,危险且不赞成使用-替代方法是强制转换:(char**) lastname = value;,或采用C ++语法reinterpret_cast<char**>(lastname) = value。 如果有人教您使用这两种方法中的任一种,请更换老师。