C字符串嵌套拆分

时间:2017-06-03 09:37:54

标签: c string split

我是C的初学者,我遇到了一个简单的问题。这就是:
我有一个格式如下的字符串:“first1:second1 \ nsecond2 \ nfirst3:second3”......依此类推。
从示例中可以看出,第一个字段是可选的([firstx:] secondx) 我需要得到一个只包含第二个字段的结果字符串。像这样:“second1 \ nsecond2 \ nsecond3”。

我在堆栈上做了一些研究(string splitting in C),我发现C中有两个主要的函数用于字符串拆分: strtok (过时)和 strsep
我尝试使用这两个函数(加上 strdup )编写代码但没有成功。大多数时候我得到一些不可预知的结果。

更好的想法?
提前致谢

修改
这是我的第一次尝试

int main(int argc, char** argv){
    char * stri = "ciao:come\nva\nquialla:grande\n";
    char * strcopy = strdup(stri); // since strsep and strtok both modify the input string
    char * token;
    while((token = strsep(&strcopy, "\n"))){
        if(token[0] != '\0'){ // I don't want the last match of '\n'
            char * sub_copy = strdup(token);
            char * sub_token = strtok(sub_copy, ":");
            sub_token = strtok(NULL, ":");
            if(sub_token[0] != '\0'){
                printf("%s\n", sub_token);
            }
        }
        free(sub_copy);
    }
    free(strcopy);
}

预期输出:“来”,“si”,“格兰德”

1 个答案:

答案 0 :(得分:2)

以下是strcspn的解决方案:

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

int main(void) {
    const char *str = "ciao:come\nva\nquialla:grande\n";
    const char *p = str;
    while (*p) {
        size_t n = strcspn(p, ":\n");
        if (p[n] == ':') {
            p += n + 1;
            n = strcspn(p , "\n");
        }
        if (p[n] == '\n') {
            n++;
        }
        fwrite(p, 1, n, stdout);
        p += n;
    }
    return 0;
}

我们计算不包含:\n的初始细分的大小。如果后跟:,我们会跳过它并获取下一个不包含\n的细分。

如果后跟\n,我们会在细分中包含换行符。然后我们只需要输出当前段并更新p以继续以相同的方式处理字符串的其余部分。

我们在*p'\0'时停止,即在到达字符串末尾时停止。