【问题标题】:How could I get directory name from the full path without using dirname()?如何在不使用 dirname() 的情况下从完整路径中获取目录名称?
【发布时间】:2017-08-29 05:13:06
【问题描述】:

dirname() 真的很糟糕,因为它修改了参数,因此它需要原始字符串的另一个丑陋副本。所以请不要使用 dirname()。

有没有类似的功能但又能安全使用?

【问题讨论】:

  • 我用的是C,那我就去掉C++标签。
  • @EsmaeelE - 返回当前工作目录。这与从完整路径中提取文件夹名称完全不同。 (例如,可能存在于网络共享或类似位置 - 一个没有当前工作目录概念的位置);)

标签: c


【解决方案1】:

编辑:修复我愚蠢时的可怕解决方法(两年前);

std::string_view getDirName(std::string_view filePath) {
    return filePath.substr(0, filePath.rfind('/'));
}

【讨论】:

  • 它需要原始字符串的另一个丑陋副本”您展示的解决方案不是也可以吗?
  • 正如您明确提到的使用 C:那些对 fullpathmalloc() 的强制转换非常无用。 index 应该是 size_tsizeof (char) 根据定义等于 1。
  • 缺少对strdupmalloc 失败的检查。
【解决方案2】:

标准 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);

(当然你应该freedircbasec,并且上面的代码不检查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);

顺便说一句,glib 提供g_path_get_dirname(其结果应该是freed)。

【讨论】:

    【解决方案3】:

    dirname(3) 的 freebsd 手册页说 dirname() 函数返回一个指向在第一次调用时分配的内部存储空间的指针,该指针将被后续调用覆盖。因此请检查您的文档。无论如何,如果你的实现直接修改输入字符串,你可以得到一个安全的调用:

    char *aux = dirname(strdup(the_path));
    ...
    free(aux);
    

    【讨论】:

      猜你喜欢
      • 2012-02-10
      • 2011-02-04
      • 1970-01-01
      • 2010-10-14
      • 1970-01-01
      • 2022-11-11
      • 1970-01-01
      • 2019-10-14
      • 2010-10-15
      相关资源
      最近更新 更多