C字符串嵌套拆分
我是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)编写代
我有一个如下格式的字符串:“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'
的情况下打印它。当然,举例来说,这样做可能会更好。但不管怎样,没关系,算了吧。