-2

I want to create file test in this path /tmp/a1/a2/a3/a4/test

But all the directories (a1..a4) doesn't exist, How can I create this file in C at Linux OS?

MicrosoctCprog
  • 460
  • 1
  • 3
  • 23
  • 2
    Does this answer your question? [Recursive mkdir() system call on Unix](https://stackoverflow.com/questions/2336242/recursive-mkdir-system-call-on-unix) – 0x5453 Aug 02 '20 at 05:09
  • @0x5453 no , that make folder , not file ... – MicrosoctCprog Aug 02 '20 at 05:11
  • 1
    You could first create, the directories, then once those are created create the file. – Durstann Aug 02 '20 at 05:12
  • First create the directories `/tmp/a1`, `/tmp/a1/a2`, `/tmp/a1/a2/a3`, `/tmp/a1/a2/a3/a4`, in that order, and then create the file `/tmp/a1/a2/a3/a4/test`. – M. Nejat Aydin Aug 02 '20 at 10:59

3 Answers3

2

You can use the mkdir function from sys/stat.h to create the directories as you need them. E.g.,

mkdir("/tmp/a1",0766);

However, you should check, via stat, whether or not the directories exist already.

Once you've created the directory structure, your file can be created with

open("/tmp/a1/a2/a3/a4/test",O_WRONLY|O_CREAT);

Obviously, you need to check the return values of all of these function calls.

Daniel Walker
  • 6,380
  • 5
  • 22
  • 45
2

Below is a complete function in C that achieves what you want.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>

int create_file_with_parent_dirs (char pathname[])
{
    for (char *p = pathname; (p = strchr(p ,'/')) != NULL; ++p) {
        char c = p[1];
        p[1] = '\0';
        errno = 0;
        if (mkdir(pathname, 0700) != 0 && errno != EEXIST) {
            perror("mkdir");
            return -1;
        }
        p[1] = c;
    }
    int fd = creat(pathname, 0600);
    if (fd < 0)
        perror("creat");
    return fd;
}

int main (void)
{
    char pathname[] = "/tmp/a1/a2/a3/a4/test";
    create_file_with_parent_dirs(pathname);
}

Note that the array pointed to by pathname must be modifiable. Do not call the function with a string literal. Also beware that the file will be truncated to zero length if it already exists.

M. Nejat Aydin
  • 9,597
  • 1
  • 7
  • 17
-1

You can use this code. This program split the path and check whether the path exist or not if not create the path and create the final path as file.

 #include <dirent.h>
 #include <errno.h>
 #include <bits/stdc++.h>
 #include <iostream>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <vector>
 #include <fstream>
 using namespace std;
 int checkDir(char * path)
 {
    DIR* dir = opendir(path);
    if (dir) {
            
            /* Directory exists. */
            closedir(dir);
            return 0;
    } else if (ENOENT == errno) {
            /* Directory does not exist. */
            return -1;
    } else {
            /* opendir() failed for some other reason. */
            return -2;
    }
 }
 int make_dir(char *path)
 {
    int ret = checkDir(path);
    if( ret == -1)
         {
                 if (mkdir(path, 0777) == -1)
            {
                         cerr << "Error :  " << strerror(errno) << endl;
                    return -1;
            }
 
                 else
            {
                         cout << "Directory created";
                    return 0;
            } 
         }
    return ret;
 
 }
 int main(int args, char **argv)
 {
    std::string strpath(argv[1]);
    std::string delimeter = "/";
    std::string substr1 = "";
    int cnt = 0;
    std::vector<string> strPaths;
    std::string strbck = strpath;

            for( int i = strpath.find(delimeter);  i != std::string::npos; i = strpath.find(delimeter))
    {
            if(cnt > 0)
            {
                    substr1 = strbck.substr(0,  substr1.length() + i + 1);
                    strPaths.push_back(substr1);
            }

            strpath = strpath.substr(i +1,strpath.length());
            cnt++;
    }
    strPaths.push_back(strbck);
    std::string str;

    for_each( strPaths.begin() ,strPaths.end() -1 , [](std::string str) {make_dir((char*)str.c_str());});
    ofstream outfile;
    std::ofstream file {strPaths[strPaths.size() -1].c_str() };
    file << "hello"<< std::endl;
    file.close();
                    return 0;
 }
Farhad Sarvari
  • 1,051
  • 7
  • 13