繁体   English   中英

ANSI C中的字符串处理

[英]String handling in ANSI C

假设我收到以下路径

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

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

"home/directory"

我想编码这样的东西

char* _get_ParentDir(char* file_path);

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

首先,不要给函数起一个下划线。 此类标识符保留给实现。

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

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

这样就可以修改字符串了,但是您需要一个函数。 编写一个返回指向字符串的指针的函数很棘手。 您不必担心为字符串分配空间。 共有三种常见方法:

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

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

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

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

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(),这取决于所需的寿命。 如果在应用程序执行期间需要它,则完全不需要free(),操作系统将在应用程序退出时自动回收进程的整个虚拟地址空间。

还要注意,strdup()是必需的,因为您对char * path的分配是从静态const字符串初始化程序进行的,该初始化程序很可能在程序的只读部分中分配(可能是.rodata,具体取决于编译器)。

仅在最后一个斜杠处粘贴'\\ 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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM