0

假设我收到以下路径

char* path = "home/directory/file.txt"

我怎么能处理这个字符串来获取只是file.txt的父目录来获取这个

"home/directory"

我想编写以这种方式工作的东西

char* _get_ParentDir(char* file_path);

并且该函数将返回父路径。

4

3 回答 3

4

首先,不要给你的函数起一个下划线开头的名字。这样的标识符保留给实现。

根据您的描述,您可以将最后一个/字符替换为空字符:

char *last_slash = strrchr(path, '/');
if (last_slash != NULL) {
    *last_slash = '\0';
}

这会修改字符串 - 但您需要一个函数。编写一个返回指向字符串的指针的函数很棘手。您必须担心为字符串分配空间。常见的方法有以下三种:

  1. 在函数中声明一个static数组,并返回一个指向其第一个元素的指针。问题:对函数的每次调用都会破坏任何先前调用使用的缓冲区。

  2. 让调用者将指针传递给写入结果的缓冲区。这使调用者的事情变得更加复杂。

  3. 让函数使用分配缓冲区malloc()(并确保检查分配失败)。这可行,但它使调用者稍后负责free()处理缓冲区。

您的系统还可能提供为您执行此操作的功能。另一个答案提到了一个dirname()函数<libgen.h>。这是由 POSIX 指定的,但不是由 C 标准指定的;您的系统可能有也可能没有。您应该阅读手册页(man 3 dirname如果您使用的是类 Unix 系统),尤其是 NOTES 部分。

于 2012-06-29T23:34:26.500 回答
1
const char* bname=path;
bname+=strlen(path);
while (bname>path && bname[-1]!='\\' && bname[-1]!='/')
   --bname;

还有 basename() 函数,但我的版本适用于 DOS 和 Unix/Linux 路径。

[编辑:我想提一下,在欧内斯特·弗里德曼-希尔在下面发表评论的大约同一时间,我自己发布了以下内容。在那之后,我继续发布我的其余答案。-phonetagger] 哎呀...我倒读了你的问题。你想要 dirname() 函数。 #include <libgen.h>

或者....

const char* dname = strdup(path);
const char* bname = dname;
if (dname)
{
   bname+=strlen(path);
   while (bname>dname && bname[-1]!='\\' && bname[-1]!='/')
      --bname;
   if (bname != dname)
      bname[-1] = '\0';
   else
   {
      bname = path;
      free(dname);
      dname = NULL;
   }
}

请注意,此版本为 dname 分配了一个新字符串,您可能想要也可能不想 free(),这取决于您需要它拥有的寿命。如果您在应用程序执行期间需要它,则根本不需要 free() 它,操作系统将在应用程序退出时自动回收您进程的整个虚拟地址空间。

另请注意,strdup() 是必需的,因为您对 char* 路径的分配来自静态 const 字符串初始化程序,该初始化程序很可能分配在程序的只读部分(可能是 .rodata,具体取决于您的编译器)。

于 2012-06-29T23:31:22.820 回答
1

只是在最后一个斜杠上加上一个 '\0' 可能会对原始字符串产生意想不到的副作用。为避免这种情况,您需要创建另一个字符串:

char* _get_ParentDir(char* file_path) {
    char *c = strrchr(file_path, "/");
    long n = c - file_path;
    char *dir = malloc(n+1); // this will need to be freed later
    dir[n] = 0;
    memcpy(dir, file_path, n);
    return dir;
}
于 2012-06-29T23:39:36.173 回答