dirname()非常糟糕,因为它修改了参数,因此它需要另一个原始字符串的丑陋副本。所以没有dirname(),请。
是否有类似的功能,但能够安全使用?
答案 0 :(得分:1)
编辑:当我愚蠢时(两年前)修复可怕的解决方法;
std::string_view getDirName(std::string_view filePath) {
return filePath.substr(0, filePath.rfind('/'));
}
答案 1 :(得分:1)
标准C99或C11不了解目录,这是一些操作系统API(或其上面的一些外部库)提供的概念。
在Linux上,dirname(3)手册页显示了调用strdup(3)的示例:
char *dirc, *basec, *bname, *dname;
char *path = "/etc/passwd";
dirc = strdup(path);
basec = strdup(path);
dname = dirname(dirc);
bname = basename(basec);
printf("dirname=%s, basename=%s\n", dname, bname);
(当然您应该free
dirc
和basec
,并且上面的代码不会检查strdup
的失败
您可能还需要使用realpath(3)的路径的规范目录。例如,您可以编码:
char* filepath = something();
char* canpath = realpath(filepath, NULL);
if (!canpath) { perror("realpath"); exit(EXIT_FAILURE); };
// so canpath is malloc-ed
char *candir = dirname(canpath); // would modify the string in canpath
/// use candir here, e.g.
printf("canonical directory for %s is %s\n", filepath, candir);
free (canpath);
BTW,glib提供g_path_get_dirname(其结果应为free
d)。
答案 2 :(得分:0)
dirname(3)
的freebsd手册页说明了 dirname()函数返回指向第一次调用时分配的内部存储空间的指针,该调用将被后续调用覆盖。所以检查你的文档。无论如何,如果您的实现直接使用以下命令修改输入字符串,则可以获得安全调用:
char *aux = dirname(strdup(the_path));
...
free(aux);