从C中的字符串中获取子字符串

时间:2014-04-24 21:22:35

标签: c string split

我有这样的字符串(它是一个实际代表系统路径的字符串):

./home/user/dir1/dir2/

现在,我希望能够创建显示的目录树,所以我需要创建home,user,dir1,dir2。

我知道如何在Linux中用C创建dirs,但是在切断字符串时会遇到麻烦。基本上,我现在需要的是拥有一个字符串数组:

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

如果我有这样的数组,那么制作呈现的dir树会很容易,但是如何以这种方式分割字符串呢?

3 个答案:

答案 0 :(得分:1)

这有点天真,但它应该让你开始。它将处理可能有或没有尾随/以及转义路径的路径,例如./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;
}

答案 1 :(得分:1)

我选择Sean的建议为#34;你应该只执行()mkdir -p ...并且让自己免于头痛。&#34;

但是如果有必要,你可以去:

#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;
}

输出结果为:

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

答案 2 :(得分:1)

我会使用strtok来解析字符串中的目录名称,使用"/"作为分隔符。

请参阅:http://www.cplusplus.com/reference/cstring/strtok/

继承人我是怎么做到的:

#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;
}

输出是:

.
home
user
dir1
dir2