0

I have such string (it's a string that represents a system path actually):

./home/user/dir1/dir2/

And now, I would like to be able to create presented directory tree, so I need to create home, user, dir1, dir2.

I know how to create dirs in C in Linux, but have troubles with chopping off the string. Basically, what I need now is to have an array of strings:

tmp[0] = "./home/";
tmp[1] = "./home/user/";
tmp[2] = "./home/user/dir1/";
tmp[3] = "./home/user/dir1/dir2/";

and if I will hav such array it would be pretty easy to make presented dir tree but how to split the string in that way?

6
  • If you iterate backwards from the last character, you can copy the array at various points using '/' as your separator. Commented Apr 24, 2014 at 21:24
  • @JDong: I use / as my path separator Commented Apr 24, 2014 at 21:25
  • 1
    You can split the string into an array of substrings with the strtok standard function. Commented Apr 24, 2014 at 21:26
  • 3
    You should just exec() mkdir -p ... and save yourself the headache. Commented Apr 24, 2014 at 21:28
  • "how to split the string in that way?" - think about it. naive algorithm: find nth /, copy string up until its position. Rinse, repeat. Commented Apr 24, 2014 at 21:34

3 Answers 3

1

This is a bit naive but it should get you started. It will handle paths that may or may not have a trailing / and also escaped paths, such as ./home/some\/user/dir1/dir2

#include <stdio.h>                                                                                                                  
#include <string.h>

int main(int argc, char *argv[])
{
    char path[] = "./home/user/dir1/dir2";
    char *start = path;
    char *end = start + strlen(path);

    while (start < end) {
        char *slash = strchr(start, '/');

        if (slash) {
            if (slash > path && *(slash - 1) == '\\') {
                start = slash + 1;
                continue;
            }

            *slash = 0;
        }

        if (strcmp(start, ".") != 0) {
            /* Use 'path' for mkdir here */
            /* mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) or whatever */
            printf("going to make %s\n", path);
        }

        if (!slash) {
            break;
        }

        *slash = '/';
        start = slash + 1;
    }

    return 0;
}
Sign up to request clarification or add additional context in comments.

Comments

1

I'd go for Sean's advice as "You should just exec() mkdir -p ... and save yourself the headache."

However if C is necessary, there you go:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define BUF_SIZE 100

int main(){
    char s[] = "./home/user/dir1/dir2/";
    char** tmp;
    int i, j;
    int size = 0;
    char* token;

    /* count the '/' characters */
    char c = s[0];
    int count = 0;
    i = 0;
    while (c != '\0'){
        if (s[i] == '/')
            count++;

        i++;
        c = s[i];
    }

    size = i;

    /* ready the tmp array */
    tmp = (char**)malloc(count);
    for (i = 0; i < count; i++){
        tmp[i] = (char*)malloc(BUF_SIZE);
        for (j = 0; j < BUF_SIZE; ++j)
            tmp[i][j] = '\0';
    }

    /* special treatment for our first tmp[] */
    tmp[0][0] = '.';
    tmp[0][1] = '/';


    i = 0;
    /* tokenize the main string */
    token = strtok(s, "./");
    while (token != NULL){

        if (i > 0)
            strcat(tmp[i], tmp[i - 1]);

        strcat(tmp[i], token);
        strcat(tmp[i], "/");
        printf("%s\n", tmp[i]);

        token = strtok(NULL, "/");
        i++;
    }

    /* clean up */
    for (i = 0; i < count; i++)
        free(tmp[i]);

    getchar();
    return 0;
}

The output is:

./home/
./home/user/
./home/user/dir1/
./home/user/dir1/dir2/

Comments

1

I would use strtok to parse the directory names from the string using "/" as the delimiter.

see: http://www.cplusplus.com/reference/cstring/strtok/

Heres how I did it:

#include <stdio.h>
#include <string.h>

// Count the number of times the character appears in the string
size_t countInstances(char* str, char token) {
    size_t count = 0;
    while(*str) {
        if(*str == token) {
            count++;
        }
        str++;
    }

    return count;
}

int main() {
    char path[] = "./home/user/dir1/dir2/"; // strtok might segfault if this is a pointer (rather than an array)

    size_t count = countInstances(path, '/');
    char** dirs = malloc(sizeof(*dirs) * count);
    char* dir;
    size_t i = 0;

    dir = strtok(path, "/");
    while(dir && i < count) {
        dirs[i] = dir; // store reference

        printf("%s\n",dir);
        dir = strtok (NULL, "/");
        i++;
    }

    free(dirs);
    return 0;
}

output is:

.
home
user
dir1
dir2

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.