假设我有一个功能:
void split_path_file(char** p, char** f, char *pf)
{
//malloc and set *p to file path, malloc and set *f to file name
//pf is the pointer to the full file and path "C:\sponge\bob\square.pants"
// edit: leave pf in its origional state
}
最好的方法是什么?
答案 0 :(得分:7)
void split_path_file(char** p, char** f, char *pf) {
char *slash = pf, *next;
while ((next = strpbrk(slash + 1, "\\/"))) slash = next;
if (pf != slash) slash++;
*p = strndup(pf, slash - pf);
*f = strdup(slash);
}
(如果pf == slash
,则没有目录组件。)
答案 1 :(得分:3)
参加聚会可能有点晚了,但我找到并且多年来一直使用的最佳解决方案是两个函数dirname
和basename
path dirname basename
"/usr/lib" "/usr" "lib"
"/usr/" "/" "usr"
"usr" "." "usr"
"/" "/" "/"
它们非常适合分离路径/文件名的各个部分。与realpath()一起,它们在简单和强大方面是无与伦比的。
答案 2 :(得分:1)
向前翻阅字符串直到你到达第一个'\\'然后将* f设置为它之后的所有内容和* p之前的所有内容和'\\'。
答案 3 :(得分:1)
最简单的方法似乎是从头开始并朝着开始工作,寻找第一个分隔符。然后你有两个案例:要么你找到了一个,要么你没找到。这样的事情应该为你做到:
#include <stdlib.h>
#include <string.h>
void split_path_file(char **p, char **f, char *pf) {
char *newcopy = malloc(strlen(pf) + 1);
strcpy(newcopy, pf);
for (z=newcopy+strlen(newcopy); z>newcopy; z--) {
if (*z == '/' || *z == '\\')
break;
}
if (z > newcopy) {
*p = newcopy;
*z = '\0';
*f = z+1;
} else {
*f = newcopy;
*p = NULL;
}
}
更新:@ ephemient的评论下面指出上述方法不会让*p
和*f
适合调用free()
。如果这很重要,那么需要更复杂的东西:
#include <stdlib.h>
#include <string.h>
void split_path_file(char **p, char **f, char *pf) {
/* Find last delimiter. */
char *z;
for (z=pf+strlen(pf); z>=pf; z--) {
if (*z == '/' || *z == '\\')
break;
}
if (z >= pf) {
/* There is a delimiter: construct separate
path and filename fragments. */
printf("--> %i\n", z-pf);
*p = malloc(z-pf+1);
strncpy(*p, pf, z-pf);
(*p)[z-pf] = '\0';
*f = malloc(strlen(z));
strcpy(*f, z+1);
} else {
/* There is no delimiter: the entire
string must be a filename. */
*p = NULL;
*f = malloc(strlen(pf)+1);
strcpy(*f, pf);
}
}
答案 4 :(得分:0)
我想出了以下内容,当然这假设pf是malloced。
void split_path_file(char** p, char **f, char *pf)
{
char *posp = strrchr(pf, '\\');
*posp = '\0';
*p = strdup(pf);
*f = strdup(posp+1);
*posp = '\\';
}
不确定这是否比上述答案更好。
答案 5 :(得分:0)
int stripfilenameandpath (char *path, char *onlypath, char *onlyfilename) { /* documentacao path = path com path e arquivo onlypath = somente o path onlyfilename = somente o arquivo sem o path */ int ret; int i; int p; char temp[255]; char *fixo; #ifdef WIN32 const int separator = '\\'; #else const int separator = '/'; #endif fixo = path; if (path == NULL) { if (onlypath != NULL) { memset (onlypath, 0, 1); } if (onlyfilename != NULL) { memset (onlyfilename, 0, 1); } return 1; } ret = strlen (path); if (!ret) { if (onlypath != NULL) { memset (onlypath, 0, 1); } if (onlyfilename != NULL) { memset (onlyfilename, 0, 1); } return 0; } for (i = 0; i -1; i--) { if (temp[i] == separator) { temp[i + 1] = 0; break; } p++; } p = ret - p; fixo += p + 1; if (onlypath != NULL) { strcpy (onlypath, temp); } if (onlyfilename != NULL) { strcpy (onlyfilename, fixo); } return 0; }