如何将char复制到char *向量中

时间:2016-01-13 09:26:32

标签: c++ stdvector dirent.h

我正在使用dirent从特定文件夹中读取文件名,我想将名称保存在char *向量中。它似乎是在复制一些奇怪的符号而不是复制文件名。这是我到目前为止所尝试的:

reverseLoop

任何人都可以告诉我为什么它不复制文件名,我该如何复制它们?

修改 d_name是声明为:

的char变量
std::vector<char*> filenames;

int filenamesAndNumberOfFiles(char *dir)
{
    struct dirent *dp;
    DIR *fd;
    int count = 0;

    if ((fd = opendir(dir)) == NULL) 
    {
        fprintf(stderr, "listdir: can't open %s\n", dir);
        return 0;
    }
    while ((dp = readdir(fd)) != NULL) 
    {
        if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
            continue;    /* skip self and parent */
        printf("Filename: %s\n", dp->d_name);
        filenames.push_back(dp->d_name);
        count++;
    }
    closedir(fd);
    return count;
}

似乎在我的程序中PATH_MAX等于260。

PS:这是我第一次使用dirent,所以我对它并不熟悉。

4 个答案:

答案 0 :(得分:6)

geom_ribbon替换为library(tidyr) library(dplyr) condquant <- dfm %>% group_by(step) %>% do(quant = quantile(.$value, probs = seq(0,1,.05)), probs = seq(0,1,.05)) %>% unnest() %>% mutate(delta = 2*round(abs(.5-probs)*100)) %>% group_by(step, delta) %>% summarize(quantmin = min(quant), quantmax= max(quant)) ggplot() + geom_ribbon(data = condquant, aes(x = step, ymin = quantmin, ymax = quantmax, group = reorder(delta, -delta), fill = as.numeric(delta)), alpha = .5) + scale_fill_gradient(low = "grey10", high = "grey95") + geom_line(data = dfm, aes(x = step, y = value, group=variable), alpha=0.2) + geom_line(data=ensemble_av,aes(step,ensav),size=2)+ theme(legend.position="none") 。并添加std::vector<char*>。这应该可以解决问题。

似乎你还没有掌握C / C ++中指针和数组的概念,而且我不确定解释是否符合SO答案的限制。但这个答案可能有用:C++ : Does char pointer to std::string conversion copy the content?

简而言之,代码的问题在于,不是复制存储字符串的内存(字符本身,std::vector<std::string>),而是只复制指向该内存的指针(#include <string>) 。并且指向的内存块后来被重用甚至删除,使您存储的指针无效。

答案 1 :(得分:3)

您需要存储字符串的副本。使用vector<string>。当您push_back(dp->d_name)存储悬空指针时,因为dp在函数结束后超出范围。

答案 2 :(得分:3)

这是因为你将一个指针dp->d_name推到了向量上,但是当你调用下一个readdir()调用时,这个指针指向的字符串就消失了。

相反,您必须复制该字符串,并将其推送到矢量:

filenames.push_back(strdup(dp->d_name));

现在,您必须记住在完成filenames向量

后,释放()复制到向量中的此字符串

但是,请不要这样做。只需使用:

std::vector<std::string> filenames;

您可以在此处使用原始代码,并将负责内存管理。

答案 3 :(得分:1)

正如user2079303所说,对readdir的第二次调用将覆盖第一次调用(link)返回的结果。

但我建议你在C ++中使用一个字符串:

std::vector<std::string> filenames;

int filenamesAndNumberOfFiles(char *dir)
{
    struct dirent *dp;
    DIR *fd;
    int count = 0;

    if ((fd = opendir(dir)) == NULL) 
    {
        fprintf(stderr, "listdir: can't open %s\n", dir);
        return 0;
    }
    while ((dp = readdir(fd)) != NULL) 
    {
        if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
            continue;    /* skip self and parent */
        printf("Filename: %s\n", dp->d_name);
        filenames.push_back( std::string(dp->d_name) );
        count++;
    }
    closedir(fd);
    return count;
}

如果您稍后需要c_str(),则可以随时使用char*