프로그램이 실행되는 디렉토리는 어떻게 얻습니까? 디렉토리의 전체 경로를 가져

C / C ++를 사용하여 프로그램이 실행되고있는 디렉토리의 전체 경로를 가져 오는 플랫폼에 구애받지 않고 파일 시스템에 구애받지 않는 방법이 있습니까? 현재 작업 디렉토리와 혼동하지 마십시오. (clib 또는 STL과 같은 표준 라이브러리가 아닌 경우 라이브러리를 제안하지 마십시오.)

(플랫폼 / 파일 시스템과 무관 한 방법이 없다면, 특정 파일 시스템에 대해 Windows 및 Linux에서 작동하는 제안도 환영합니다.)



답변

실행중인 앱의 전체 경로를 얻는 코드는 다음과 같습니다.

윈도우 :

int bytes = GetModuleFileName(NULL, pBuf, len);
return bytes ? bytes : -1;

리눅스 :

int bytes = MIN(readlink("/proc/self/exe", pBuf, len), len - 1);
if(bytes >= 0)
    pBuf[bytes] = '\0';
return bytes;


답변

프로그램을 처음 시작할 때 현재 디렉토리를 가져 오면 프로그램이 시작된 디렉토리를 효과적으로 갖게됩니다. 변수에 값을 저장하고 나중에 프로그램에서 참조하십시오. 이것은 현재 실행 가능한 프로그램 파일을 보유한 디렉토리 와 다릅니다 . 반드시 같은 디렉토리 일 필요는 없습니다. 누군가 명령 프롬프트에서 프로그램을 실행 하면 프로그램 파일이 다른 곳에 존재하더라도 명령 프롬프트의 현재 작업 디렉토리 에서 프로그램이 실행 되고 있습니다.

getcwd는 POSIX 기능이며 모든 POSIX 호환 플랫폼에서 기본적으로 지원됩니다. 유닉스에서는 올바른 헤더 unistd.h와 윈도우에서는 direct.h를 포함하는 것 외에는 특별한 작업을 수행 할 필요가 없습니다.

C 프로그램을 작성 중이므로 시스템의 모든 프로세스에 의해 링크 된 기본 c 런타임 라이브러리와 링크되며 (특히 조작 된 예외는 피함) 기본적으로이 기능을 포함합니다. CRT는 OS에 대한 기본 표준 호환 인터페이스를 제공하므로 외부 라이브러리로 간주되지 않습니다.

Windows에서 getcwd 기능은 _getcwd를 위해 더 이상 사용되지 않습니다. 이 방식으로 사용할 수 있다고 생각합니다.

#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);


답변

이것은 cplusplus 포럼에서 온 것입니다

Windows에서 :

#include <string>
#include <windows.h>

std::string getexepath()
{
  char result[ MAX_PATH ];
  return std::string( result, GetModuleFileName( NULL, result, MAX_PATH ) );
}

Linux에서 :

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

std::string getexepath()
{
  char result[ PATH_MAX ];
  ssize_t count = readlink( "/proc/self/exe", result, PATH_MAX );
  return std::string( result, (count > 0) ? count : 0 );
}

HP-UX에서 :

#include <string>
#include <limits.h>
#define _PSTAT64
#include <sys/pstat.h>
#include <sys/types.h>
#include <unistd.h>

std::string getexepath()
{
  char result[ PATH_MAX ];
  struct pst_status ps;

  if (pstat_getproc( &ps, sizeof( ps ), 0, getpid() ) < 0)
    return std::string();

  if (pstat_getpathname( result, PATH_MAX, &ps.pst_fid_text ) < 0)
    return std::string();

  return std::string( result );
}


답변

라이브러리가없는 표준 방법을 원할 경우 : 아니오. 디렉토리의 전체 개념이 표준에 포함되지 않습니다.

근사 표준 라이브러리에 대한 (이동식) 의존성이 괜찮다면, Boost의 파일 시스템 라이브러리 를 사용하고 initial_path ()를 요청하십시오 .

좋은 업보로 얻을 수있는 가장 가까운 IMHO (부스트는 잘 확립 된 고품질 라이브러리 세트)


답변

파일 시스템 TS 는 이제 표준 이며 gcc 5.3+ 및 clang 3.9+에서 지원되므로 다음과 같은 current_path()기능을 사용할 수 있습니다 .

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

gcc (5.3+)에서 파일 시스템을 포함하려면 다음을 사용해야합니다.

#include <experimental/filesystem>

코드와 -lstdc++fs플래그를 연결하십시오 .

Microsoft Visual Studio에서 파일 시스템을 사용하려면 이 내용읽으십시오 .


답변

나는 이것에 대한 답변을 던지는 것이 매우 늦다는 것을 알고 있지만, 내 대답만큼 유용한 답변이 없다는 것을 알았습니다. CWD에서 bin 폴더로의 경로를 얻는 매우 간단한 방법은 다음과 같습니다.

int main(int argc, char* argv[])
{
    std::string argv_str(argv[0]);
    std::string base = argv_str.substr(0, argv_str.find_last_of("/"));
}

이제 이것을 상대 경로의 기본으로 사용할 수 있습니다. 예를 들어이 디렉토리 구조가 있습니다.

main
  ----> test
  ----> src
  ----> bin

소스 코드를 bin으로 컴파일하고 테스트 할 로그를 작성하여 코드 에이 줄을 추가 할 수 있습니다.

std::string pathToWrite = base + "/../test/test.log";

나는 전체 경로, 별명 등을 사용하여 Linux 에서이 접근법을 시도했지만 제대로 작동합니다.

노트:

창에있는 경우 ‘/’가 아닌 파일 구분 기호로 ‘\’를 사용해야합니다. 예를 들어 이것을 피해야합니다.

std::string base = argv[0].substr(0, argv[0].find_last_of("\\"));

나는 이것이 작동해야하지만 테스트되지는 않았다고 생각하므로 그것이 작동하면 의견을 주시면 안됩니다.


답변

아니요, 표준적인 방법은 없습니다. C / C ++ 표준은 디렉토리 (또는 다른 파일 시스템 조직)의 존재조차 고려하지 않는다고 생각합니다.

Windows에서 hModule 매개 변수가 NULL 로 설정 되면 GetModuleFileName () 은 현재 프로세스의 실행 파일에 대한 전체 경로를 리턴합니다 . 나는 리눅스를 도울 수 없다.

또한 현재 디렉토리 또는 프로그램 이미지 / 실행 파일이있는 디렉토리를 원하는지 확인해야합니다. 그것은 당신의 질문이 약간 모호합니다.