我正在使用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,所以我对它并不熟悉。
答案 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*
。