Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C字符串嵌套拆分_C_String_Split - Fatal编程技术网

C字符串嵌套拆分

C字符串嵌套拆分,c,string,split,C,String,Split,我是C语言的初学者,我被困在一个简单的问题上。下面是: 我有一个如下格式的字符串:“first1:second1\nsecond2\nfirst3:second3”。。。等等。 从示例中可以看到,第一个字段是可选的([firstx:]secondx)。 我需要得到一个只包含第二个字段的结果字符串。像这样:“第二个1\n第二个2\n第三个” 我在这里对stack()做了一些研究,发现C中有两个用于字符串拆分的主要函数:strtok(过时)和strep 我尝试使用这两个函数(加上strdup)编写代

我是C语言的初学者,我被困在一个简单的问题上。下面是:
我有一个如下格式的字符串:“first1:second1\nsecond2\nfirst3:second3”。。。等等。
从示例中可以看到,第一个字段是可选的([firstx:]secondx)。
我需要得到一个只包含第二个字段的结果字符串。像这样:“第二个1\n第二个2\n第三个”

我在这里对stack()做了一些研究,发现C中有两个用于字符串拆分的主要函数:strtok(过时)和strep
我尝试使用这两个函数(加上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);
}

预期输出:“come”、“si”、“grande”

下面是一个带有
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;
}
#包括
#包括
内部主(空){
const char*str=“ciao:come\nva\nquilla:grande\n”;
const char*p=str;
而(*p){
尺寸n=strcspn(p,“:\n”);
如果(p[n]==':'){
p+=n+1;
n=strcspn(p,“\n”);
}
如果(p[n]='\n'){
n++;
}
fwrite(p,1,n,stdout);
p+=n;
}
返回0;
}
我们计算不包含
\n
的初始段的大小。如果后面跟着一个
,我们跳过它,得到下一个不包含
\n
的段

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


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

下面是一个使用
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;
}
#包括
#包括
内部主(空){
const char*str=“ciao:come\nva\nquilla:grande\n”;
const char*p=str;
而(*p){
尺寸n=strcspn(p,“:\n”);
如果(p[n]==':'){
p+=n+1;
n=strcspn(p,“\n”);
}
如果(p[n]='\n'){
n++;
}
fwrite(p,1,n,stdout);
p+=n;
}
返回0;
}
我们计算不包含
\n
的初始段的大小。如果后面跟着一个
,我们跳过它,得到下一个不包含
\n
的段

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


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

显示您的代码<代码>strtok()
不是过时的@JohnZwinck应该是:p,
strtok_r()
更好。@Stargateur:更好:
strspn()
/
strcspn()
。当
main()
函数的参数未使用时,请使用签名:
int main(void)
调用
strdup()
时,始终选中(!=NULL)确保操作成功的返回值显示您的代码<代码>strtok()不是过时的@JohnZwinck应该是:p,
strtok_r()
更好。@Stargateur:更好:
strspn()
/
strcspn()
。当
main()
函数的参数未使用时,请使用签名:
int main(void)
调用
strdup()
时,始终选中(!=NULL)用于确保操作正确的返回值successful@Stargateur我不明白那个评论。您建议的替换仍然输出
\n
。我想说的是,您的示例并不容易理解,OP可能希望令牌是一个“单独的字符串”。在这里,您可以在不删除字符串的原始
'\n'
的情况下打印它。当然,举例来说,这样做可能会更好。但不管怎样,没关系,算了吧。@Stargateur我不明白那个评论。您建议的替换仍然输出
\n
。我想说的是,您的示例并不容易理解,OP可能希望令牌是一个“单独的字符串”。在这里,您可以在不删除字符串的原始
'\n'
的情况下打印它。当然,举例来说,这样做可能会更好。但不管怎样,没关系,算了吧。