4

Today I did a lot of research online about how to create a directory on C++ and found a lot of way to do that, some easier than others.

I tried the _mkdir function using _mkdir("C:/Users/..."); to create a folder. Note that the argument of function will be converted into a const char*.

So far, so good, but when I want to change the path, it does not work (see the code below). I have a default string path "E:/test/new", and I want to create 10 sub-folders: new1, new2, newN, ..., new10.

To do that, I concatenate the string with a number (the counter of the for-loop), converted into char using static_cast, then I transform the string using c_str(), and assign it to a const char* variable.

The compiler has no problem compiling it, but it doesn't work. It prints 10 times "Impossible create folder n". What's wrong?

I probably made a mistake when transforming the string using c_str() to a get a const char*?.

Also, is there a way to create a folder using something else? I looked at CreateDirectory(); (API) but it uses keyword like DWORD HANDLE, etc., that are a little bit difficult to understand for a no-advanced level (I don't know what these mean).

#include <iostream>
#include <Windows.h>
#include<direct.h>

using namespace std;

int main()
{
int stat;
string path_s = "E:/test/new";

for (int i = 1; i <= 10; i++)
{
    const char* path_c = (path_s + static_cast<char>(i + '0')).c_str();
    stat = _mkdir(path_c);

    if (!stat)
        cout << "Folder created " << i << endl;
    else
        cout << "Impossible create folder " << i << endl;
    Sleep(10);
}
return 0;
}
4
  • 2
    i + '0' won't work very well when i == 10. Perhaps you should use std::to_string instead? Commented Aug 5, 2019 at 12:38
  • And the Windows CreateDirectoryA function is really easy to use: Pass the path as the first argument, and a null pointer as the second. Commented Aug 5, 2019 at 12:41
  • 2
    You might be interested in new (C++17) file system library, you wouldn't rely on (non-standard!) mkdir any more... Commented Aug 5, 2019 at 12:42
  • Does "E:/test" exist? I'm pretty sure _mkdir will only create one level of directory. Commented Aug 5, 2019 at 13:04

3 Answers 3

11

If your compiler supports c++17, you can use filesystem library to do what you want.

#include <filesystem>
#include <string>
#include <iostream>

namespace fs = std::filesystem;

int main(){
    const std::string path = "E:/test/new";
    for(int i = 1; i <= 10; ++i){
        try{
            if(fs::create_directory(path + std::to_string(i)))
                std::cout << "Created a directory\n";
            else
                std::cerr << "Failed to create a directory\n";\
        }catch(const std::exception& e){
            std::cerr << e.what() << '\n';
        }
    }
    return 0;
}
Sign up to request clarification or add additional context in comments.

Comments

4

The problem is that (path_s + static_cast<char>(i + '0')) creates a temporary object. One whose life-time ends (and is destructed) just after c_str() has been called.

That leaves you with a pointer to a string that no longer exist, and using it in almost any way will lead to undefined behavior.

Instead save the std::string object, and call c_str() just when needed:

std::string path = path_s + std::to_string(i);
_mkdir(path.c_str());

Comments

2

Note that under Linux, you can use the mkdir command as follows:

#include <sys/stat.h>
... 
const int dir_err = mkdir("foo", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
if (-1 == dir_err){
    printf("Error creating directory!n");
    exit(1);
}

More information on it can be gleaned from reading man 2 mkdir.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.