填充char **

时间:2011-02-18 16:28:34

标签: c++

我正在尝试从另一个文件中读取文件列表。文件读取有效但填充char *数组不是。它适用于第一次迭代,但随后在下一行得到一个错误的指针。我尝试使用字符串向量但遇到问题,我认为由于它的析构函数试图释放argv。

char **datafiles = (char**)malloc(0);
int filecount = 0;

master.AddDataFiles(argv[1],datafiles,filecount);

int Manager::AddDataFiles(char *filename, char **filelist, int &filecount)
{
    const int LINEMAX = 64;
    struct stat info;
    std::ifstream is(filename);
    if (is.fail()) return 1;

    char buffer[LINEMAX];

    while(!is.eof())
    {
        is.getline(buffer,LINEMAX);
        realloc(filelist,sizeof(char**) * (filecount + 1));
        filelist[filecount] = (char*) malloc(std::strlen(buffer) + 1);
        std::strcpy(filelist[filecount],buffer);
        filecount++;
    }

    return 0;
}

3 个答案:

答案 0 :(得分:5)

正确使用realloc有点棘手 - 它可以(有时但不总是会)返回与传递给它的指针不同的指针,因此您必须执行以下操作:< / p>

char **temp = realloc(filelist, sizeof(char**) * filecount+1);
if (temp != NULL)
    filelist = temp;
else
    failed_allocation();

另请注意,您的while (!file.eof())是一个经典错误 - 它无法正确判断文件的结尾。

我会重新审视字符串选项的向量。也许您可以发布您拥有的代码,并询问您遇到的任何问题。让它运作良好几乎肯定会比修复它更少工作,结果几乎肯定会更加坚实和可理解。

正确的代码如下所示:

std::vector<std::string> Manager::AddDataFiles(std::string const &filename) { 
   std::ifstream infile(filename.cstr());
   std::vector<std::string> filenames;
   std::string temp;
   while (std::getline(infile, temp))
       filenames.push_back(temp);
   return filenames;
}

答案 1 :(得分:2)

为什么不使用std::vector<std::string>代替char**?这优雅地解决了您的问题!

如果文件名不包含空格,那么这里是更优雅的解决方案(或者你可以看到Jerry的解决方案):

void Manager::AddDataFiles(const char *filename, std::vector<std::string> &filelist)
{
    std::istream_iterator<string> start(std::ifstream(filename));
    std::istream_iterator<string> end;
    std::copy(start, end, std::back_inserter(filelist));
}

为此,您需要包含以下内容:

#include <iterator>
#include <algorithm>
#include <vector>
#include <string>

答案 2 :(得分:0)

使用std::stringstd::vector<std::string>。将文件列表作为成员也可能是有意义的。

#include <fstream>
#include <string>
#include <vector>

void Manager::AddDataFiles(const std::string& filename)
{
    std::ifstream in(filename.c_str());
    for( std::string line; std::getline(in, line); ) {
        filelist.push_back(line);
    }
}