How do I get the directory that a program is runni

2018-12-31 09:25发布

Is there a platform-agnostic and filesystem-agnostic method to obtain the full path of the directory from where a program is running using C/C++? Not to be confused with the current working directory. (Please don't suggest libraries unless they're standard ones like clib or STL.)

(If there's no platform/filesystem-agnostic method, suggestions that work in Windows and Linux for specific filesystems are welcome too.)

20条回答
素衣白纱
2楼-- · 2018-12-31 09:36

If you fetch the current directory when your program first starts, then you effectively have the directory your program was started from. Store the value in a variable and refer to it later in your program. This is distinct from the directory that holds the current executable program file. It isn't necessarily the same directory; if someone runs the program from a command prompt, then the program is being run from the command prompt's current working directory even though the program file lives elsewhere.

getcwd is a POSIX function and supported out of the box by all POSIX compliant platforms. You would not have to do anything special (apart from incliding the right headers unistd.h on Unix and direct.h on windows).

Since you are creating a C program it will link with the default c run time library which is linked to by ALL processes in the system (specially crafted exceptions avoided) and it will include this function by default. The CRT is never considered an external library because that provides the basic standard compliant interface to the OS.

On windows getcwd function has been deprecated in favour of _getcwd. I think you could use it in this fashion.

#include <stdio.h>  /* defines FILENAME_MAX */
#ifdef WINDOWS
    #include <direct.h>
    #define GetCurrentDir _getcwd
#else
    #include <unistd.h>
    #define GetCurrentDir getcwd
 #endif

 char cCurrentPath[FILENAME_MAX];

 if (!GetCurrentDir(cCurrentPath, sizeof(cCurrentPath)))
     {
     return errno;
     }

cCurrentPath[sizeof(cCurrentPath) - 1] = '\0'; /* not really required */

printf ("The current working directory is %s", cCurrentPath);
查看更多
浅入江南
3楼-- · 2018-12-31 09:36

Maybe concatenate the current working directory with argv[0]? I'm not sure if that would work in Windows but it works in linux.

For example:

#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char **argv) {
    char the_path[256];

    getcwd(the_path, 255);
    strcat(the_path, "/");
    strcat(the_path, argv[0]);

    printf("%s\n", the_path);

    return 0;
}

When run, it outputs:

jeremy@jeremy-desktop:~/Desktop$ ./test
/home/jeremy/Desktop/./test

查看更多
步步皆殇っ
4楼-- · 2018-12-31 09:37

Filesystem TS is now a standard ( and supported by gcc 5.3+ and clang 3.9+ ), so you can use current_path() function from it:

std::string path = std::experimental::filesystem::current_path();

In gcc (5.3+) to include Filesystem you need to use:

#include <experimental/filesystem>

and link your code with -lstdc++fs flag.

If you want to use Filesystem with Microsoft Visual Studio, then read this.

查看更多
泪湿衣
5楼-- · 2018-12-31 09:37

On Windows the simplest way is to use the _get_pgmptr function in stdlib.h to get a pointer to a string which represents the absolute path to the executable, including the executables name.

char* path;
_get_pgmptr(&path);
printf(path); // Example output: C:/Projects/Hello/World.exe
查看更多
梦该遗忘
6楼-- · 2018-12-31 09:38

If you want a standard way without libraries: No. The whole concept of a directory is not included in the standard.

If you agree that some (portable) dependency on a near-standard lib is okay: Use Boost's filesystem library and ask for the initial_path().

IMHO that's as close as you can get, with good karma (Boost is a well-established high quality set of libraries)

查看更多
裙下三千臣
7楼-- · 2018-12-31 09:38

The linux bash command which progname will report a path to program.

Even if one could issue the which command from within your program and direct the output to a tmp file and the program subsequently reads that tmp file, it will not tell you if that program is the one executing. It only tells you where a program having that name is located.

What is required is to obtain your process id number, and to parse out the path to the name

In my program I want to know if the program was executed from the user's bin directory or from another in the path or from /usr/bin. /usr/bin would contain the supported version. My feeling is that in Linux there is the one solution that is portable.

查看更多
登录 后发表回答