The simplest way seems to be to start from the end and work towards the beginning, looking for the first delimiter character. You then have two cases: either you found one or you didn't. Something like this should do it for you:
#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;
}
}
Update: @ephemient's comment below points out the above approach doesn't leave *p
and *f
suitable for calling free()
. If this is important, something a little more complicated like this will be needed:
#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);
}
}