如何将 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()