ANSI C中的字符串处理

时间:2012-06-29 23:24:24

标签: c string path filesystems

假设我收到以下路径

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

如何处理此字符串以获取file.txt的父目录来获取此

"home/directory"

我想用这种方式编写代码

char* _get_ParentDir(char* file_path);

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

3 个答案:

答案 0 :(得分:4)

首先,不要给你的函数命名,以下划线开头。此类标识符保留给实现。

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

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

它修改了字符串 - 但你想要一个函数。编写一个返回指向字符串的指针的函数很棘手;你必须担心为字符串分配空间。有三种常见的方法:

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

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

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

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

答案 1 :(得分:1)

const char* bname=path;
bname+=strlen(path);
while (bname>path && bname[-1]!='\\' && bname[-1]!='/')
   --bname;

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

[编辑:我想提一下,我发布了以下内容,与Ernest Friedman-Hill在下面发表评论的时间差不多。在那之后,我继续发布我的其余答案。 -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(),具体取决于您需要的生命周期。如果您在应用程序执行期间需要它,则根本不需要释放它(),操作系统将在应用程序退出时自动回收您的进程的整个虚拟地址空间。

还要注意strdup()是必要的,因为你的char *路径的赋值来自一个静态的const字符串初始化器,它很可能是在程序的只读部分中分配的(也许.rodata,取决于你的编译器)。

答案 2 :(得分: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;
}