88

In my app I want to copy a file to the other hard disk so this is my code:

 #include <windows.h>

using namespace std;

int main(int argc, char* argv[] )
{
    string Input = "C:\\Emploi NAm.docx";
    string CopiedFile = "Emploi NAm.docx";
    string OutputFolder = "D:\\test";
    CopyFile(Input.c_str(), string(OutputFolder+CopiedFile).c_str(), TRUE);

    return 0;
}

so after executing this, it shows me in the D:HDD a file testEmploi NAm.docx but I want him to create the test folder if it doesn't exist.

I want to do that without using the Boost library.

Vertexwahn
  • 7,709
  • 6
  • 64
  • 90
pourjour
  • 1,186
  • 2
  • 13
  • 28

10 Answers10

87

Use the WINAPI CreateDirectory() function to create a folder.

You can use this function without checking if the directory already exists as it will fail but GetLastError() will return ERROR_ALREADY_EXISTS:

if (CreateDirectory(OutputFolder.c_str(), NULL) ||
    ERROR_ALREADY_EXISTS == GetLastError())
{
    // CopyFile(...)
}
else
{
     // Failed to create directory.
}

The code for constructing the target file is incorrect:

string(OutputFolder+CopiedFile).c_str()

this would produce "D:\testEmploi Nam.docx": there is a missing path separator between the directory and the filename. Example fix:

string(OutputFolder+"\\"+CopiedFile).c_str()
hmjd
  • 120,187
  • 20
  • 207
  • 252
  • thanks for fast answer so how can i mix it with the CopyFile member – pourjour Feb 10 '12 at 22:32
  • Prior to calling `CopyFile()` call `CreateDirectory()` to create `OutputFolder`. – hmjd Feb 10 '12 at 22:34
  • Does this function gets "ERROR_ALREADY_EXISTS" if path is just "C:\" ? Thanks – Keshava GN May 18 '17 at 13:41
  • 4
    [For those who reach the error](https://stackoverflow.com/questions/33001284/incompatible-with-parametr-of-type-lpcwstr) `argument of type "const char *" is incompatible with parameter of type "LPCWSTR"`. – baru Jun 23 '17 at 07:51
  • Small caveat: CreateDirectory also returns if lpPathName points to an existing *file* so one might wrongly assume it is a directory, and in this case the CopyFile call would probably fail – stijn Mar 28 '18 at 18:57
  • There is an issue with this solution I think, because you need to include the windows.h library which has a lot of macros that ignore scope. This can make it completely incompatible with other libraries. – Elliott May 28 '19 at 10:59
  • 1
    @baru if you get LPCWSTR you can change the function **CreateDirectory** to **CreateDirectoryA** – Ruben Medrano Apr 17 '21 at 17:19
66
#include <experimental/filesystem> // or #include <filesystem> for C++17 and up
    
namespace fs = std::experimental::filesystem;


if (!fs::is_directory("src") || !fs::exists("src")) { // Check if src folder exists
    fs::create_directory("src"); // create src folder
}
Vertexwahn
  • 7,709
  • 6
  • 64
  • 90
42

Probably the easiest and most efficient way is to use boost and the boost::filesystem functions. This way you can build a directory simply and ensure that it is platform independent.

const char* path = _filePath.c_str();
boost::filesystem::path dir(path);
if(boost::filesystem::create_directory(dir))
{
    std::cerr<< "Directory Created: "<<_filePath<<std::endl;
}

boost::filesystem::create_directory - documentation

Gelldur
  • 11,187
  • 7
  • 57
  • 68
Chris Rayner
  • 437
  • 4
  • 2
21

Here is the simple way to create a folder.......

#include <windows.h>
#include <stdio.h>

void CreateFolder(const char * path)
{   
    if(!CreateDirectory(path ,NULL))
    {
        return;
    }
}


CreateFolder("C:\\folder_name\\")

This above code works well for me.

Fivee Arch
  • 294
  • 3
  • 7
  • 24
    Thanks for including the .h file reference, which for us newbies is hard to determine. – John Sep 09 '15 at 19:58
  • 1
    There is an issue with this solution I think, because the windows.h library has a lot of macros that ignore scope. This can make it completely incompatible with other libraries. – Elliott May 28 '19 at 11:22
10

_mkdir will also do the job.

_mkdir("D:\\test");

https://msdn.microsoft.com/en-us/library/2fkk4dzw.aspx

leoly
  • 8,468
  • 6
  • 32
  • 33
9

Since c++17, you can easily do this cross-platform with:

#include <filesystem>
int main() {
bool created_new_directory = false;
bool there_was_an_exception = false;

try {
  created_new_directory
      = std::filesystem::create_directory("directory_name");
} catch(std::exception & e){
there_was_an_exception = true;
// creation failed
}
if ((not created_new_directory) and (not there_was_an_exception)) {
    // no failure, but the directory was already present.
  }
}

Note, that this version is very useful, if you need to know, whether the directory is actually newly created. And I find the documentation on cppreference slightly difficult to understand on this point: If the directory is already present, this function returns false.

This means, you can more or less atomically create a new directory with this method.

Eike
  • 359
  • 3
  • 8
  • Is the directory creation guaranteed to be atomic? Just asking because I couldn't find such information on cppreference.com. – starriet Oct 13 '22 at 10:02
  • 1
    No, therefore the "more or less". It depends on the operating system and cannot be guaranteed by c++. I think it is atomic in POSIX systems if using local filesystems (not over network), but don't quote me on that. Although I have used this on Linux and not gotten a failure of atomicity, yet. – Eike Oct 14 '22 at 11:10
6

OpenCV Specific

Opencv supports filesystem, probably through its dependency Boost.

#include <opencv2/core/utils/filesystem.hpp>
cv::utils::fs::createDirectory(outputDir);
saurabheights
  • 3,967
  • 2
  • 31
  • 50
  • P.S. - This answer helps mostly students/researchers who have to work on computer vision projects but do not need Boost specifically. – saurabheights Dec 27 '18 at 17:55
  • Does this function destroy the folder if it exists? – KansaiRobot Dec 23 '21 at 01:21
  • 1
    @KansaiRobot https://github.com/opencv/opencv/blob/17234f82d025e3bbfbf611089637e5aa2038e7b8/modules/core/src/utils/filesystem.cpp#L232 It just emulates linux mkdir command. So if a folder already exists, it returns true. No directory should get deleted. – saurabheights Dec 23 '21 at 04:13
3

This works in GCC:

Taken from: Creating a new directory in C

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

struct stat st = {0};

if (stat("/some/directory", &st) == -1) {
    mkdir("/some/directory", 0700);
}
driedler
  • 3,750
  • 33
  • 26
3

Use CreateDirectory (char *DirName, SECURITY_ATTRIBUTES Attribs);

If the function succeeds it returns non-zero otherwise NULL.

Vertexwahn
  • 7,709
  • 6
  • 64
  • 90
DotNetUser
  • 6,494
  • 1
  • 25
  • 27
2

You can use cstdlib

Although- http://www.cplusplus.com/articles/j3wTURfi/

#include <cstdlib>

const int dir= system("mkdir -p foo");
if (dir< 0)
{
     return;
}

you can also check if the directory exists already by using

#include <dirent.h>
Noa Yehezkel
  • 468
  • 2
  • 4
  • 20