sub
sub

Reputation: 2743

C++ argv path specifier

In the interpreter for my programming languages I have to correctly handle the parts in case the import function is called. I then need to check if such a file is in the /libs folder (located at the same place as my executeable!) and if it doesn't exist I have to check in the directory of the current script.

Upvotes: 0

Views: 5526

Answers (6)

Alain Rist
Alain Rist

Reputation: 837

For Windows (non portable) use ::GetModuleFileName() and ::PathRemoveFileSpec():

TCHAR sPath[MAX_PATH] = {0};
if(::GetModuleFileName(NULL, sPath, MAX_PATH))
    ::PathRemoveFileSpec(sPath))
// sPath is the executable path if the module is an exe

Upvotes: 0

jweyrich
jweyrich

Reputation: 32260

Not optimal, but works fine:

int main(int argc, char **argv) {
    using namespace std;
    char buffer[MAXPATHLEN];
    realpath(argv[0], buffer);
    string fullpath = buffer;
    fullpath = string(fullpath, 0, fullpath.rfind("/"));
    cout << fullpath << endl;
}

For relative path I'm using realpath(), which is unix/linux specific. For windows you could use GetModuleFileName(NULL, buffer, MAXPATHLEN), and of course the separator isn't the same.

Upvotes: 0

frankc
frankc

Reputation: 11483

If your environment has the equivalent of PWD in the environment, you can just append /$argv[0] to it.

This might give you something you don't expect like /foo1/foo2/../foo3/ but that's ok. It's a valid path and can be globbed.

Upvotes: 1

R Samuel Klatchko
R Samuel Klatchko

Reputation: 76611

  1. There is no guaranteed way to do that. You can try looking in argv[0] but whether that has the full path or just the name of the binary depends on the platform and how your process was invoked.
  2. You can use strrchr to find the last slash and replace the character after it with '\0'

Code example:

// Duplicate the string so as not to trash the original
// You can skip this if you don't mind modifying the original data
// and the originald is writeable (i.e. no literal strings)
char *path = strdup(...);

char *last_slash = strrchr(path, '/');
if (last_slash)
{
#if PRESERVE_LAST_SLASH
    *(last_slash + 1) = '\0';
#else
    *last_slash = '\0';
#endif
}

Upvotes: 2

nategoose
nategoose

Reputation: 12392

A non-portable way on Linux (and maybe other *nix) would be to use readlink on /proc/self/exe if argv[0] doesn't contain the entire path.

Upvotes: 2

Judge Maygarden
Judge Maygarden

Reputation: 27613

Scan backwards from the end of a string for the first '/' character.

Upvotes: 0

Related Questions