What is the simplest way to get the directory that a file is in? I'm using this to find the working directory.
string filename = "C:\MyDirectory\MyFile.bat"
In this example, I should get "C:\MyDirectory".
What is the simplest way to get the directory that a file is in? I'm using this to find the working directory.
string filename = "C:\MyDirectory\MyFile.bat"
In this example, I should get "C:\MyDirectory".
The initialisation is incorrect as you need to escape the backslashes:
string filename = "C:\\MyDirectory\\MyFile.bat";
To extract the directory if present:
string directory;
const size_t last_slash_idx = filename.rfind('\\');
if (std::string::npos != last_slash_idx)
{
directory = filename.substr(0, last_slash_idx);
}
The quick and dirty:
Note that you must also look for /
because it is allowed alternative path separator on Windows
#include <string>
#include <iostream>
std::string dirnameOf(const std::string& fname)
{
size_t pos = fname.find_last_of("\\/");
return (std::string::npos == pos)
? ""
: fname.substr(0, pos);
}
int main(int argc, const char *argv[])
{
const std::string fname = "C:\\MyDirectory\\MyFile.bat";
std::cout << dirnameOf(fname) << std::endl;
}
Use the Boost.filesystem parent_path() function.
Ex. argument c:/foo/bar => c:/foo
More examples here : path decomposition table and tutorial here.
C++17 provides std::filesystem::path. It may be available in C++11 in ; link with -lstdc++fs. Note the function does not validate the path exists; use std::filesystem::status to determine type of file (which may be filetype::notfound)
The MFC way;
#include <afx.h>
CString GetContainingFolder(CString &file)
{
CFileFind fileFind;
fileFind.FindFile(file);
fileFind.FindNextFile();
return fileFind.GetRoot();
}
or, even simpler
CString path(L"C:\\my\\path\\document.txt");
path.Truncate(path.ReverseFind('\\'));
Since C++17 you can use std::filesystem::parent_path:
#include <filesystem>
#include <iostream>
int main() {
std::string filename = "C:\\MyDirectory\\MyFile.bat";
std::string directory = std::filesystem::path(filename).parent_path().u8string();
std::cout << directory << std::endl;
}
As Question is old but I would like to add an answer so that it will helpful for others.
in Visual c++ you can use CString or char array also
CString filename = _T("C:\\MyDirectory\\MyFile.bat");
PathRemoveFileSpec(filename);
OUTPUT:
C:\MyDirectory
Include Shlwapi.h
in your header files.
MSDN LINK here you can check example.
A very simple cross-platform solution (as adapted from this example for string::find_last_of
):
std::string GetDirectory (const std::string& path)
{
size_t found = path.find_last_of("/\\");
return(path.substr(0, found));
}
This works for both cases where the slashes can be either backward or forward pointing (or mixed), since it merely looks for the last occurrence of either in the string path
.
However, my personal preference is using the Boost::Filesystem libraries to handle operations like this. An example:
std::string GetDirectory (const std::string& path)
{
boost::filesystem::path p(path);
return(p.parent_path().string());
}
Although, if getting the directory path from a string is the only functionality you need, then Boost might be a bit overkill (especially since Boost::Filesystem is one of the few Boost libraries that aren't header-only). However, AFIK, Boost::Filesystem had been approved to be included into the TR2 standard, but might not be fully available until the C++14 or C++17 standard (likely the latter, based on this answer), so depending on your compiler (and when you're reading this), you may not even need to compile these separately anymore since they might be included with your system already. For example, Visual Studio 2012 can already use some of the TR2 filesystem components (according to this post), though I haven't tried it since I'm still using Visual Studio 2010...
You can use the _spliltpath function available in stdlib.h header. Please refer to this link for the same.
http://msdn.microsoft.com/en-us/library/aa273364%28v=VS.60%29.aspx
This is proper winapi solution:
CString csFolder = _T("c:\temp\file.ext");
PathRemoveFileSpec(csFolder.GetBuffer(0));
csFolder.ReleaseBuffer(-1);
If you have access to Qt, you can also do it like this:
std::string getDirectory(const std::string & file_path)
{
return QFileInfo(QString(file_path)).absolutePath().toStdString();
}
The way of Beetle)
#include<tchar.h>
int GetDir(TCHAR *fullPath, TCHAR *dir) {
const int buffSize = 1024;
TCHAR buff[buffSize] = {0};
int buffCounter = 0;
int dirSymbolCounter = 0;
for (int i = 0; i < _tcslen(fullPath); i++) {
if (fullPath[i] != L'\\') {
if (buffCounter < buffSize) buff[buffCounter++] = fullPath[i];
else return -1;
} else {
for (int i2 = 0; i2 < buffCounter; i2++) {
dir[dirSymbolCounter++] = buff[i2];
buff[i2] = 0;
}
dir[dirSymbolCounter++] = fullPath[i];
buffCounter = 0;
}
}
return dirSymbolCounter;
}
Using :
TCHAR *path = L"C:\\Windows\\System32\\cmd.exe";
TCHAR dir[1024] = {0};
GetDir(path, dir);
wprintf(L"%s\n%s\n", path, dir);
You can simply search the last "\" and then cut the string:
string filePath = "C:\MyDirectory\MyFile.bat"
size_t slash = filePath.find_last_of("\");
string dirPath = (slash != std::string::npos) ? filePath.substr(0, slash) : filePath;
make sure in Linux to search "/" instead of "\":
size_t slash = filePath.find_last_of("/");