[英]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';
}
这样就可以修改字符串了,但是您需要一个函数。 编写一个返回指向字符串的指针的函数很棘手。 您不必担心为字符串分配空间。 共有三种常见方法:
在函数中声明一个static
数组,并返回一个指向其第一个元素的指针。 问题:每次调用该函数都会破坏以前的调用所使用的缓冲区。
让调用者将指针传递到将结果写入其中的缓冲区。 这使调用者的事情变得更加复杂。
让函数使用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.