繁体   English   中英

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

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

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

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

}

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

有效使用的结构使用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的位置,您可以分配相关实体并接受该结果将导致内存泄漏,除非调用者可以清除该结果。

你不能只是撒东西。 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结尾。 这是一个单独的问题,您可以解决。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM