结构传染媒介

时间:2015-01-05 21:22:24

标签: c++

我试图在循环中创建一个结构向量,但是向量的所有元素最终都具有相同的值(最后一个)。

我认为将元素推回到向量上会复制结构。

以下是代码:

std::vector<struct ftpparse> parse_result;
std::istringstream is(ftp_result);

for (std::string line; getline(is, line); )
{
    struct ftpparse r;
    int found = ftpparse(&r, (char*)line.c_str(), line.size());
    if (!found)
        throw std::runtime_error("error parsing ftp list");
    else
        parse_result.push_back(r);
}

struct和ftpparse函数在我链接的单独C库中提供。

修改1

这是ftp结构定义

struct ftpparse {
    char *name; /* not necessarily 0-terminated */
    int namelen;
    int flagtrycwd; /* 0 if cwd is definitely pointless, 1 otherwise */
    int flagtryretr; /* 0 if retr is definitely pointless, 1 otherwise */
    int sizetype;
    long size; /* number of octets */
    int mtimetype;
    time_t mtime; /* modification time */
    int idtype;
    char *id; /* not necessarily 0-terminated */
    int idlen;
};

此外,如果我删除struct标签,那么我会收到以下错误:

error: must use 'struct' tag to refer to type 'ftpparse' in this scope
        ftpparse r = {};
        ^
        struct

1 个答案:

答案 0 :(得分:2)

由于原始struct ftpparse包含char指针,因此向量中存储副本会有问题,因为向量不会生成深层副本。

你可以做的是调用ftpparse函数,但是push_back是一个不同的结构,它基本上是返回结构的副本,而是使用std::string而不是char *

以下是一个例子:

// Our copy of the ftpparse struct 
struct ftpparseX {
    std::string name; 
    int flagtrycwd; 
    int flagtryretr; 
    int sizetype;
    long size; 
    int mtimetype;
    time_t mtime;
    int idtype;
    std::string id; 
    ftpparseX(const ftpparse& parse) : name(parse.name, parse.namelen), // we use 2-arg ctor
                                       id(parse.id, parse.idlen),   // we use 2-arg ctor
                                       flagtrycws(parse.flagtrycws),
                                       flagtryretr(parse.flagtryretr),
                                       sizetype(parse.sizetype),
                                       size(parse.size),
                                       mtimetype(parse.mtimetype),
                                       mtime(parse.mtime),
                                       idtype(parse.idtype) {}
};
//....

std::vector<ftpparseX> parse_result;
std::istringstream is(ftp_result);
for (std::string line; getline(is, line); )
{
    ftpparse r;
    int found = ftpparse(&r, (char*)line.c_str(), line.size());
    if (!found)
        throw std::runtime_error("error parsing ftp list");
    else
        parse_result.push_back(ftpparseX(r));
}

基本上,我们像往常一样做所有事情,除了push_back而不是ftpparse的{​​{1}}之外,我们创建一个ftpparseX对象并将其推回去,给构造函数{ {1}}我们从函数中返回

这样您可以将名称和ID保存为ftpparse个对象。还要注意如何使用2参数std::string构造函数构造字符串。这意味着std::stringname具有length属性,并且不一定是以null结尾。