如果我们有多个分隔符,如何提取字符串?

如果我有这个代码:

int main () { char *sentence = "Wisteria#Tunnel"; char stringA[50]; char stringB[50]; char stringC[50]; pDelim = strstr(sentence,"#"); *pDelim = '\0'; strcpy(stringA,sentence); strcpy(stringB,(pDelim+1)); return(0); } 

运行后, stringA将是“Wisteria”, stringB将是“Tunnel”,对吧?

如果:

 char *sentence = "Wisteria#Tunnel#Japan"; 

如何将其提取为三部分, stringA将为“Wisteria”, stringB为“Tunnel”, stringC为“Japan”

谢谢。

标准字符串函数strtokstrstrstrchr都可以工作,前提是周围的代码也是正确的。 也就是说,如果要在同一源字符串中多次搜索,则需要在源的开头指向一个Start-at指针,并在每次(成功!)搜索之后将其更新为指向分隔符。 默认情况下, strtok可以正常工作 – 单个字符分隔符。 你可以在任何好的参考资料中阅读有关strtok (我不打算为你查找)。

事实上,这是一个如此简单的操作,我刚才做了这个。 除了vanilla strtok ,我的strcpyUpTo接受任何分隔符字符串。 我本可以先用strstr来检查,但我更喜欢马上复制。 复制循环内的strncmpstrlen可能效率低下; 然而,一般来说,这些低级字符串操作应该非常快。

 #include  #include  char *strcpyUpTo (const char *source, char *dest, const char *delim) { while (*source && strncmp (source, delim, strlen(delim))) *dest++ = *source++; *dest = 0; if (*source) return (char *)(source+strlen(delim)); return (char *)source; } int main (void) { char *sentence = "Wisteria#any#Tunnel#any#Japan"; char stringA[50]; char stringB[50]; char stringC[50]; char *pDelim; pDelim = strcpyUpTo (sentence, stringA, "#any#"); pDelim = strcpyUpTo (pDelim, stringB, "#any#"); pDelim = strcpyUpTo (pDelim, stringC, "#any#"); printf ("stringA = \"%s\"\n", stringA); printf ("stringB = \"%s\"\n", stringB); printf ("stringC = \"%s\"\n", stringC); return 0; } 

加成

对于未知数量的子字符串 ,您可以使用while循环,如下所示。 (对于生产代码,它需要进行各种检查。为简洁起见,为了清晰起见,以及作为读者的练习。)这基本上就是你如何使用strtok

 char resultList[10][50]; int i, n_result; pDelim = sentence; n_result = 0; do { pDelim = strcpyUpTo (pDelim, resultList[n_result], "#any#"); n_result++; } while (*pDelim && n_result < 10); printf ("number of strings: %d\n", n_result); for (i=0; i 
 #include  int main (){ char *sentence = "Wisteria#Tunnel#Japan"; char stringA[50]; char stringB[50]; char stringC[50]; sscanf(sentence, "%49[^#]#%49[^#]#%49[^#]", stringA, stringB, stringC); puts(stringA);puts(stringB);puts(stringC); return(0); } 

 #include  #include  #include  char **split(const char *str, char delimiter){ char **words = malloc(sizeof(char*)); const char *p = str; int wc = 0; for(;;){ char *pos; int len; if((pos = strchr(p, delimiter))!=NULL){ len = pos - p; words[wc] = malloc(len+1); strncpy(words[wc], p, len); words[wc][len] = '\0'; words=realloc(words, (++wc+1)*sizeof(char*)); } else { pos = strchr(p, '\0'); len = pos - p + 1; words[wc] = malloc(len); strncpy(words[wc], p, len); words=realloc(words, (++wc+1)*sizeof(char*)); words[wc] = NULL;//End Mark break; } p = pos + 1; } return words; } int main (){ char **sentences = split("Wisteria#Tunnel#Japan", '#'); int i; for(i=0;sentences[i];++i){ puts(sentences[i]); free(sentences[i]); } free(sentences[i]); free(sentences); return(0); } 

对于任何更复杂的事情,使用strtok是要走的路,但你可以使用strstr 。 我没有费心将生成的子串复制到新的字符串,只是将它们打印到控制台。 如果要保存它们,可以将所有b指针保存到数组中,也可以使用strcpy进行复制。

 #include  #include  int main () { char *sentence = "Wisteria#Tunnel#foo#bar"; char* b = sentence; while(1) { char*a = strstr(b,"#"); if (a) *a = 0; printf("%s\n",b); if (!a) break; b = a+1; } } 

输出是

Wisteria Tunnel foo bar