programing

현재 디렉토리를 얻는 방법?

yoursource 2021. 1. 16. 10:52
반응형

현재 디렉토리를 얻는 방법?


C #과 Delphi에서이 작업을 해왔지만 C ++는 사악합니다. 목적은 현재 디렉터리 (실행 파일이 실행중인)에 파일을 만드는 것입니다.

내 코드 :

LPTSTR NPath = NULL;
DWORD a = GetCurrentDirectory(MAX_PATH,NPath);
HANDLE hNewFile = CreateFile(NPath,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);

GetCurrentDirectory ()에서 예외가 발생합니다.

예외가 발생하는 이유와 C ++에서 더 쉽게 만드는 방법을 알려주세요.


더 나아 가기 전에 C ++에 관한 책을 읽는 것이 좋습니다. 기초를 확고하게하는 것이 도움이 될 것입니다. Koenig와 Moo의 Accelerated C ++ 는 훌륭합니다.

실행 가능한 경로를 얻으려면 GetModuleFileName 사용하십시오 .

char buffer[MAX_PATH];
GetModuleFileName( NULL, buffer, MAX_PATH );

다음은 파일 이름없이 디렉토리를 가져 오는 C ++ 함수입니다.

#include <windows.h>
#include <string>
#include <iostream>
using namespace std;;

string ExePath() {
    char buffer[MAX_PATH];
    GetModuleFileName( NULL, buffer, MAX_PATH );
    string::size_type pos = string( buffer ).find_last_of( "\\/" );
    return string( buffer ).substr( 0, pos);
}

int main() {
    cout << "my directory is " << ExePath() << "\n";
}

GetCurrentDirectory 결과를위한 공간을 할당하지 않습니다. 그렇게하는 것은 귀하에게 달려 있습니다.

TCHAR NPath[MAX_PATH];
GetCurrentDirectory(MAX_PATH, NPath);

또한 C ++ 방식으로이 작업을 수행하려면 Boost.Filesystem 라이브러리를 살펴보십시오 .


IMHO는 anon의 답변에 대한 몇 가지 개선 사항 입니다.

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

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

std::string GetExePath() 
{
  std::string f = GetExeFileName();
  return f.substr(0, f.find_last_of( "\\/" ));
}

질문은 현재 작업 디렉토리가 필요한지 아니면 실행 파일이 포함 된 디렉토리의 경로가 필요한지 명확하지 않습니다.

대부분의 답변은 후자에 대한 답변 인 것 같습니다.

그러나 전자와 파일 생성 문제의 두 번째 부분에 대해 C ++ 17 표준은 이제이를 많이 단순화하는 파일 시스템 라이브러리를 통합합니다.

#include <filesystem>
#include <iostream>

std::filesystem::path cwd = std::filesystem::current_path() / "filename.txt";
std::ofstream file(cwd.string());
file.close();

이것은 현재 작업 디렉토리를 가져오고 경로에 파일 이름을 추가하고 빈 파일을 생성합니다. 경로 객체는 os 종속 경로 처리를 처리하므로 cwd.string ()은 os 종속 경로 문자열을 반환합니다. Neato.


유효한 버퍼 자리 표시자를 제공해야합니다. 그건:

TCHAR s[100];
DWORD a = GetCurrentDirectory(100, s);

#include <iostream>    
#include <stdio.h>
#include <dirent.h>

std::string current_working_directory()
{
    char* cwd = _getcwd( 0, 0 ) ; // **** microsoft specific ****
    std::string working_directory(cwd) ;
    std::free(cwd) ;
    return working_directory ;
}

int main(){
    std::cout << "i am now in " << current_working_directory() << endl;
}

GetModuleFileName을 올바르게 사용하지 못했습니다. 이 작업이 아주 잘 작동한다는 것을 알았습니다. 방금 Windows에서 테스트했지만 아직 Linux에서는 시도하지 않았습니다. :)


Please don't forget to initialize your buffers to something before utilizing them. And just as important, give your string buffers space for the ending null

TCHAR path[MAX_PATH+1] = L"";
DWORD len = GetCurrentDirectory(MAX_PATH, path);

Reference


#include <windows.h>
using namespace std;

// The directory path returned by native GetCurrentDirectory() no end backslash
string getCurrentDirectoryOnWindows()
{
    const unsigned long maxDir = 260;
    char currentDir[maxDir];
    GetCurrentDirectory(maxDir, currentDir);
    return string(currentDir);
}

You can remove the filename from GetModuleFileName() with more elegant way:

TCHAR fullPath[MAX_PATH];
TCHAR driveLetter[3];
TCHAR directory[MAX_PATH];
TCHAR FinalPath[MAX_PATH];
GetModuleFileName(NULL, fullPath, MAX_PATH);
_splitpath(fullPath, driveLetter, directory, NULL, NULL);
sprintf(FinalPath, "%s%s",driveLetter, directory);

Hope it helps!


GetCurrentDirectory() gets the current directory which is where the exe is invoked from. To get the location of the exe, use GetModuleFileName(NULL ...). if you have the handle to the exe, or you can derive it from GetCommandLine() if you don't.

As Mr. Butterworth points out, you don't need a handle.


WCHAR path[MAX_PATH] = {0};
GetModuleFileName(NULL, path, MAX_PATH);
PathRemoveFileSpec(path);

Why does nobody here consider using this simple code?

TCHAR szDir[MAX_PATH] = { 0 };

GetModuleFileName(NULL, szDir, MAX_PATH);
szDir[std::string(szDir).find_last_of("\\/")] = 0;

or even simpler

TCHAR szDir[MAX_PATH] = { 0 };
TCHAR* szEnd = nullptr;
GetModuleFileName(NULL, szDir, MAX_PATH);
szEnd = _tcsrchr(szDir, '\\');
*szEnd = 0;

An easy way to do this is:

int main(int argc, char * argv[]){
    std::cout << argv[0]; 
    std::cin.get();
}

argv[] is pretty much an array containing arguments you ran the .exe with, but the first one is always a path to the executable. If I build this the console shows: C:\Users\Ulisse\source\repos\altcmd\Debug\currentdir.exe


Code snippets from my CAE project with unicode development environment:

/// @brief Gets current module file path. 
std::string getModuleFilePath() {
    TCHAR buffer[MAX_PATH];
    GetModuleFileName( NULL, buffer, MAX_PATH );
    CT2CA pszPath(buffer);
    std::string path(pszPath);
    std::string::size_type pos = path.find_last_of("\\/");
    return path.substr( 0, pos);
}

Just use the templete CA2CAEX or CA2AEX which calls the internal API ::MultiByteToWideChar or ::WideCharToMultiByte


If you are using the Poco library, it's a one liner and it should work on all platforms I think.

Poco::Path::current()

To find the directory where your executable is, you can use:

TCHAR szFilePath[_MAX_PATH];
::GetModuleFileName(NULL, szFilePath, _MAX_PATH);

String^ exePath = Application::ExecutablePath;<br>
MessageBox::Show(exePath);

ReferenceURL : https://stackoverflow.com/questions/875249/how-to-get-current-directory

반응형