如何将 char 复制到 char* 向量中
How to copy a char into a char* vector
我正在使用 dirent 从特定文件夹中读取文件名,我想将名称保存在 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;
}
谁能告诉我为什么它不复制文件名,我该怎么做才能复制它们?
编辑:
d_name 是一个 char 变量声明为:
char d_name[PATH_MAX];
在我的程序中 PATH_MAX 似乎等于 260。
PS: 第一次用dirent,不是很熟悉
将 std::vector<char*>
替换为 std::vector<std::string>
。并添加 #include <string>
。那应该可以解决问题。
看来你还没有掌握C/C++中指针和数组的概念,我不确定这样解释是否符合SO答案的范围。但是这个答案可能有用:C++ : Does char pointer to std::string conversion copy the content?
简而言之,您的代码的问题在于您没有复制存储字符串的内存(字符本身,char[PATH_MAX]
),您只是复制了指向该内存的指针(char*
).而指向的内存块后来被重用甚至删除,导致你存储的指针失效。
您需要存储字符串的副本。使用 vector<string>
。当您 push_back(dp->d_name)
时,您正在存储一个悬空指针,因为 dp
在函数结束后超出范围。
这是因为您将指针 dp->d_name
压入向量,但是当您调用下一个 readdir()
调用时,该指针指向的字符串已经消失。
相反,您必须复制该字符串,并将其推送到向量中:
filenames.push_back(strdup(dp->d_name));
现在,您必须记住在完成 filenames
向量
后释放()这个复制到向量中的字符串
但是,请不要这样做。只需使用:
std::vector<std::string> filenames;
您可以在这里使用您的原始代码,内存管理将得到处理。
正如 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;
}
如果以后需要 char*
,您可以随时使用 c_str()
。
我正在使用 dirent 从特定文件夹中读取文件名,我想将名称保存在 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;
}
谁能告诉我为什么它不复制文件名,我该怎么做才能复制它们?
编辑: d_name 是一个 char 变量声明为:
char d_name[PATH_MAX];
在我的程序中 PATH_MAX 似乎等于 260。
PS: 第一次用dirent,不是很熟悉
将 std::vector<char*>
替换为 std::vector<std::string>
。并添加 #include <string>
。那应该可以解决问题。
看来你还没有掌握C/C++中指针和数组的概念,我不确定这样解释是否符合SO答案的范围。但是这个答案可能有用:C++ : Does char pointer to std::string conversion copy the content?
简而言之,您的代码的问题在于您没有复制存储字符串的内存(字符本身,char[PATH_MAX]
),您只是复制了指向该内存的指针(char*
).而指向的内存块后来被重用甚至删除,导致你存储的指针失效。
您需要存储字符串的副本。使用 vector<string>
。当您 push_back(dp->d_name)
时,您正在存储一个悬空指针,因为 dp
在函数结束后超出范围。
这是因为您将指针 dp->d_name
压入向量,但是当您调用下一个 readdir()
调用时,该指针指向的字符串已经消失。
相反,您必须复制该字符串,并将其推送到向量中:
filenames.push_back(strdup(dp->d_name));
现在,您必须记住在完成 filenames
向量
但是,请不要这样做。只需使用:
std::vector<std::string> filenames;
您可以在这里使用您的原始代码,内存管理将得到处理。
正如 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;
}
如果以后需要 char*
,您可以随时使用 c_str()
。