frozenca
frozenca

Reputation: 877

How could I get directory name from the full path without using dirname()?

dirname() is really terrible, because it modifies the argument so that it need another ugly copy of the original string. So no dirname(), please.

Is there any function like that but which is able to use safely?

Upvotes: 0

Views: 2440

Answers (3)

frozenca
frozenca

Reputation: 877

EDIT: To fix the horrible workaround when I was stupid (two years ago);

std::string_view getDirName(std::string_view filePath) {
    return filePath.substr(0, filePath.rfind('/'));
}

Upvotes: 2

Standard C99 or C11 do not know about directories, which is a notion provided by some operating system API (or some external library above it).

On Linux, dirname(3) man page shows examples calling strdup(3):

       char *dirc, *basec, *bname, *dname;
       char *path = "/etc/passwd";

       dirc = strdup(path);
       basec = strdup(path);
       dname = dirname(dirc);
       bname = basename(basec);
       printf("dirname=%s, basename=%s\n", dname, bname);

(of course you should free both dirc and basec, and the code above don't check for failure of strdup)

You might also want the canonical directory of a path, using realpath(3). For example, you would code:

char* filepath = something();
char* canpath = realpath(filepath, NULL);
if (!canpath) { perror("realpath"); exit(EXIT_FAILURE); };
// so canpath is malloc-ed
char *candir = dirname(canpath); // would modify the string in canpath
/// use candir here, e.g.
printf("canonical directory for %s is %s\n", filepath, candir);
free (canpath);

BTW, glib offers g_path_get_dirname (whose result should be freed).

Upvotes: 1

Luis Colorado
Luis Colorado

Reputation: 12668

The freebsd man page of dirname(3) says that The dirname() function returns a pointer to internal storage space allocated on the first call that will be overwritten by subsequent calls. so check your documentation. Anyway, you can get a safe call if your implementation modifies directly the input string with:

char *aux = dirname(strdup(the_path));
...
free(aux);

Upvotes: 0

Related Questions