Environment: Visual C++
This is a simple function I wrote in order to deal with creating complete (multi-level) paths.
The function works recursively, and uses std::wstring, but can actaully work on any basic_string -based string. It can deal with trailing slashes (eg. “c:temp” vs. “c:temp”), as well as network locations (eg. “\machineshared”).
You might notice the call to SetLastError(). The reason is to make it easy to verify what went wrong in case of an error – instead of handling exceptions and/or error strings, all you have to do is call GetLastError() if the function returns false.
You can use the function to make sure a directory exists before creating a file in it:
std::wstring wsFileName; int pos = wsFileName.find_last_of(L"\"); if (0 <= pos) { std::wstring wsPath = wsFileName.substr(0, pos); if (CreatePath(wsPath)) { CreateFileW(wsFileName.c_str(), ...); } else { std::wcout << L"Error #" << GetLastError() << std::endl; } }
Here is the source code:
bool CreatePath(std::wstring &wsPath)
{
DWORD attr;
int pos;
bool result = true;// Check for trailing slash:
pos = wsPath.find_last_of(SLASH);
if (wsPath.length() == pos + 1) // last character is “”
{
wsPath.resize(pos);
}// Look for existing object:
attr = GetFileAttributesW(wsPath.c_str());
if (0xFFFFFFFF == attr) // doesn’t exist yet – create it!
{
pos = wsPath.find_last_of(SLASH);
if (0 < pos)
{
// Create parent dirs:
result = CreatePath(wsPath.substr(0, pos));
}
// Create node:
result = result && CreateDirectoryW(wsPath.c_str(), NULL);
}
else if (FILE_ATTRIBUTE_DIRECTORY != attr)
{ // object already exists, but is not a dir
SetLastError(ERROR_FILE_EXISTS);
result = false;
}return result;
}