How to get Current Directory?

C++Windows

C++ Problem Overview


I want to create a file in the current directory (where the executable is running).

My code:

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

I get exception at GetCurrentDirectory().

Why am I getting an exception?

C++ Solutions


Solution 1 - C++

I would recommend reading a book on C++ before you go any further, as it would be helpful to get a firmer footing. Accelerated C++ by Koenig and Moo is excellent.

To get the executable path use GetModuleFileName:

TCHAR buffer[MAX_PATH] = { 0 };
GetModuleFileName( NULL, buffer, MAX_PATH );

Here's a C++ function that gets the directory without the file name:

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

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

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

Solution 2 - C++

The question is not clear whether the current working directory is wanted or the path of the directory containing the executable.

Most answers seem to answer the latter.

But for the former, and for the second part of the question of creating the file, the C++17 standard now incorporates the filesystem library which simplifies this a lot:

#include <filesystem>
#include <iostream>

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

This fetches the current working directory, adds the filename to the path and creates an empty file. Note that the path object takes care of os dependent path handling, so cwd.string() returns an os dependent path string. Neato.

Solution 3 - C++

GetCurrentDirectory does not allocate space for the result, it's up to you to do that.

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

Also, take a look at Boost.Filesystem library if you want to do this the C++ way.

Solution 4 - C++

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

Solution 5 - C++

IMHO here are some improvements to anon's answer.

#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( "\\/" ));
}

Solution 6 - C++

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

I failed to use GetModuleFileName correctly. I found this work very well. just tested on Windows, not yet try on Linux :)

Solution 7 - C++

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

Solution 8 - C++

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

Solution 9 - C++

You should provide a valid buffer placeholder. that is:

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

Solution 10 - C++

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

Solution 11 - C++

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!

Solution 12 - C++

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.

Solution 13 - C++

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;

Solution 14 - C++

I guess, that the easiest way to locate the current directory is to cut it from command line args.

#include <string>
#include <iostream>

int main(int argc, char* argv[])
{
  std::string cur_dir(argv[0]);
  int pos = cur_dir.find_last_of("/\\");
  
  std::cout << "path: " << cur_dir.substr(0, pos) << std::endl;
  std::cout << "file: " << cur_dir.substr(pos+1) << std::endl;
  return 0;
}

You may know that every program gets its executable name as first command line argument. So you can use this.

Solution 15 - C++

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

Solution 16 - C++

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

Poco::Path::current()

Solution 17 - C++

if you don't want to use std, you can use this code:

char * ExePath() 
{
   static char buffer[MAX_PATH] = { 0 };
   GetModuleFileName( NULL, buffer, MAX_PATH );
   char * LastSlash = strrchr(buffer, '\\');
   if(LastSlash == NULL)
    	LastSlash = strrchr(buffer, '/');
    
   buffer[LastSlash-buffer] = 0;
   return buffer;
}

Solution 18 - C++

I simply use getcwd() method for that purpose in Windows, and it works pretty well. The code portion is like following:

char cwd[256];
getcwd(cwd, 256);
string cwd_str = string(cwd);

The <unistd.h> library has to be added though.

Solution 19 - C++

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

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

Solution 20 - C++

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

Solution 21 - C++

In Windows console, you can use the system command CD (Current Directory):

std::cout << "Current Directory = ";
system("cd"); // to see the current executable directory

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionIvan ProdanovView Question on Stackoverflow
Solution 1 - C++anonView Answer on Stackoverflow
Solution 2 - C++Rasmus DallView Answer on Stackoverflow
Solution 3 - C++avakarView Answer on Stackoverflow
Solution 4 - C++user5736737View Answer on Stackoverflow
Solution 5 - C++cdigginsView Answer on Stackoverflow
Solution 6 - C++MsLateView Answer on Stackoverflow
Solution 7 - C++Jj RiveroView Answer on Stackoverflow
Solution 8 - C++Zhi WangView Answer on Stackoverflow
Solution 9 - C++yves BaumesView Answer on Stackoverflow
Solution 10 - C++freezoticView Answer on Stackoverflow
Solution 11 - C++ProXicTView Answer on Stackoverflow
Solution 12 - C++nickdView Answer on Stackoverflow
Solution 13 - C++123iamkingView Answer on Stackoverflow
Solution 14 - C++zexUltView Answer on Stackoverflow
Solution 15 - C++user3782257View Answer on Stackoverflow
Solution 16 - C++James SelvakumarView Answer on Stackoverflow
Solution 17 - C++EladView Answer on Stackoverflow
Solution 18 - C++skbrView Answer on Stackoverflow
Solution 19 - C++AndomarView Answer on Stackoverflow
Solution 20 - C++AliView Answer on Stackoverflow
Solution 21 - C++DalleurView Answer on Stackoverflow