在C ++中使用cstrings构建路径的正确方法

时间:2010-10-09 04:52:52

标签: c++ string concatenation cstring

我需要建立一个文件路径。我有以下类方法:

void Directory::scanDirectory(char *directory) {
    DIR *dirp;
    struct dirent *entry;
    char path[1];

    if(dirp = opendir(directory)) {
        while(entry = readdir(dirp)) {
            if (entry->d_name[0] != '.') {
                strcpy(path, directory);
                strcat(path, "/");
                strcat(path, entry->d_name);
                if (entry->d_type == 8) {
                    // Files
                } else if (entry->d_type == 4) {
                    //scanDirectory(path);
                }
                printf("Name: %s, Type: %d\n", entry->d_name, entry->d_type);
            }
        }
        closedir(dirp);
    }
}

我需要通过连接目录和entry->d_name来建立文件路径。当我尝试运行此代码时,会出现段错误。从我所知道的是我在构建路径时的分段。有没有更好的方法呢?

5 个答案:

答案 0 :(得分:3)

您只为路径分配一个字节(char path[1])。您需要分配足够的空间来实际保存您正在创建的整个路径。给定C ++标记,显而易见的可能是使用std::string,并且在将所有部分组合成完整路径之后,使用其c_str()成员函数来访问内容一个C风格的字符串。

答案 1 :(得分:2)

为什么不使用Boost.Filesystem

答案 2 :(得分:1)

缓冲区path需要有足够的空间来容纳整个路径。现在它只有一个角色的空间。试着把它做大。 strcat本身不分配空间。您必须手动管理该内存。

至于更好的方法,您可能需要考虑使用string。您不必担心内存,可以与+运算符连接。

答案 3 :(得分:1)

char path[1];更改为:

char path[512]; //or whatever value you like.

在您的代码中,路径仅为1个字符和\0分配空间。你需要一个更大的一个,据我所知,在unix中,目录名最多可以包含255个字符,所以在我看来512就足够了。

答案 4 :(得分:1)

小心使用strcpy。它不进行边界检查,因此即使path仅为char[1],它也会尝试将所有directory复制到其中。这可能是你的错误。

您在如何构建字符串方面有很多选择。这是关于C ++字符串连接效率的长篇文章:

Efficient string concatenation in C++

如果您使用的是C ++,是否有任何理由不能将内置string库与+运算符一起使用? E.g:

string path;
//...
path += directory;
path += "/";
path += entry->d_name;
//etc.

使用string类可能效率稍差,但它还有一个额外的好处,可以帮助您避免缓冲区溢出问题和内存异常,例如您正在获取的分段错误(我不是说{{ 1}}将避免所有这些,但它会让你的生活更轻松。)

还有一篇关于如何在C ++中构建目录字符串的SO帖子:

c++ how to create a directory from a path