我需要建立一个文件路径。我有以下类方法:
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
来建立文件路径。当我尝试运行此代码时,会出现段错误。从我所知道的是我在构建路径时的分段。有没有更好的方法呢?
答案 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帖子: