How do I get the directory that a program is running from?

后端 未结 23 1640
温柔的废话
温柔的废话 2020-11-22 04:39

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

相关标签:
23条回答
  • 2020-11-22 05:00

    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)

    0 讨论(0)
  • 2020-11-22 05:00

    For relative paths, here's what I did. I am aware of the age of this question, I simply want to contribute a simpler answer that works in the majority of cases:

    Say you have a path like this:

    "path/to/file/folder"
    

    For some reason, Linux-built executables made in eclipse work fine with this. However, windows gets very confused if given a path like this to work with!

    As stated above there are several ways to get the current path to the executable, but the easiest way I find works a charm in the majority of cases is appending this to the FRONT of your path:

    "./path/to/file/folder"
    

    Just adding "./" should get you sorted! :) Then you can start loading from whatever directory you wish, so long as it is with the executable itself.

    EDIT: This won't work if you try to launch the executable from code::blocks if that's the development environment being used, as for some reason, code::blocks doesn't load stuff right... :D

    EDIT2: Some new things I have found is that if you specify a static path like this one in your code (Assuming Example.data is something you need to load):

    "resources/Example.data"
    

    If you then launch your app from the actual directory (or in Windows, you make a shortcut, and set the working dir to your app dir) then it will work like that. Keep this in mind when debugging issues related to missing resource/file paths. (Especially in IDEs that set the wrong working dir when launching a build exe from the IDE)

    0 讨论(0)
  • 2020-11-22 05:01

    For Windows system at console you can use system(dir) command. And console gives you information about directory and etc. Read about the dir command at cmd. But for Unix-like systems, I don't know... If this command is run, read bash command. ls does not display directory...

    Example:

    int main()
    {
        system("dir");
        system("pause"); //this wait for Enter-key-press;
        return 0;
    }
    
    0 讨论(0)
  • 2020-11-22 05:02

    On POSIX platforms, you can use getcwd().

    On Windows, you may use _getcwd(), as use of getcwd() has been deprecated.

    For standard libraries, if Boost were standard enough for you, I would have suggested Boost::filesystem, but they seem to have removed path normalization from the proposal. You may have to wait until TR2 becomes readily available for a fully standard solution.

    0 讨论(0)
  • 2020-11-22 05:04

    Just my two cents, but doesn't the following code portably work in C++17?

    #include <iostream>
    #include <filesystem>
    namespace fs = std::filesystem;
    
    int main(int argc, char* argv[])
    {
        std::cout << "Path is " << fs::path(argv[0]).parent_path() << '\n';
    }
    

    Seems to work for me on Linux at least.

    Based on the previous idea, I now have:

    std::filesystem::path prepend_exe_path(const std::string& filename, const std::string& exe_path = "");
    

    With implementation:

    fs::path prepend_exe_path(const std::string& filename, const std::string& exe_path)
    {
        static auto exe_parent_path = fs::path(exe_path).parent_path();
        return exe_parent_path / filename;
    }
    

    And initialization trick in main():

    (void) prepend_exe_path("", argv[0]);
    

    Thanks @Sam Redway for the argv[0] idea. And of course, I understand that C++17 was not around for many years when the OP asked the question.

    0 讨论(0)
  • 2020-11-22 05:04

    Works with starting from C++11, using experimental filesystem, and C++14-C++17 as well using official filesystem.

    application.h:

    #pragma once
    
    //
    // https://en.cppreference.com/w/User:D41D8CD98F/feature_testing_macros
    //
    #ifdef __cpp_lib_filesystem
    #include <filesystem>
    #else
    #include <experimental/filesystem>
    
    namespace std {
        namespace filesystem = experimental::filesystem;
    }
    #endif
    
    std::filesystem::path getexepath();
    

    application.cpp:

    #include "application.h"
    #ifdef _WIN32
    #include <windows.h>    //GetModuleFileNameW
    #else
    #include <limits.h>
    #include <unistd.h>     //readlink
    #endif
    
    std::filesystem::path getexepath()
    {
    #ifdef _WIN32
        wchar_t path[MAX_PATH] = { 0 };
        GetModuleFileNameW(NULL, path, MAX_PATH);
        return path;
    #else
        char result[PATH_MAX];
        ssize_t count = readlink("/proc/self/exe", result, PATH_MAX);
        return std::string(result, (count > 0) ? count : 0);
    #endif
    }
    
    0 讨论(0)
提交回复
热议问题