在c中使用strtok

我需要使用strtok读取名字和姓氏并将其分开。 如何在两个单独的char数组中存储我可以独立使用它们的名称?

#include  #include  int main () { char str[] ="test string."; char * test; test = strtok (str," "); while (test != NULL) { printf ("%s\n",test); test= strtok (NULL, " "); } return 0; } 

这是我对一个相当简单的tokenize帮助器的看法

  • 存储导致数组动态增长
  • null终止数组
  • 保持输入字符串安全 (strtok修改输入字符串,这是文字char []上的未定义行为 ,至少我认为在C99中)

要使代码可重入,请使用非标准的strtok_r

 #include  #include  #include  char** tokenize(const char* input) { char* str = strdup(input); int count = 0; int capacity = 10; char** result = malloc(capacity*sizeof(*result)); char* tok=strtok(str," "); while(1) { if (count >= capacity) result = realloc(result, (capacity*=2)*sizeof(*result)); result[count++] = tok? strdup(tok) : tok; if (!tok) break; tok=strtok(NULL," "); } free(str); return result; } int main () { char** tokens = tokenize("test string."); char** it; for(it=tokens; it && *it; ++it) { printf("%s\n", *it); free(*it); } free(tokens); return 0; } 

这是一个无strtok免费重新实现(使用strpbrk代替):

 char** tokenize(const char* str) { int count = 0; int capacity = 10; char** result = malloc(capacity*sizeof(*result)); const char* e=str; if (e) do { const char* s=e; e=strpbrk(s," "); if (count >= capacity) result = realloc(result, (capacity*=2)*sizeof(*result)); result[count++] = e? strndup(s, es) : strdup(s); } while (e && *(++e)); if (count >= capacity) result = realloc(result, (capacity+=1)*sizeof(*result)); result[count++] = 0; return result; } 

你需要单独存放它们吗? 两个指向修改的char数组的指针将产生两个独立的完全可用的字符串。

那就是我们改变这个:

 char str[] ="test string."; 

进入这个:

 char str[] ="test\0string."; ^ ^ | | char *s1 ----- | char *s2 ----------- 

 #include  #include  int main () { char str[] ="test string."; char *firstname = strtok(str, " "); char *lastname = strtok(NULL, " "); if (!lastname) lastname = ""; printf("%s, %s\n", lastname, firstname); return 0; } 

使用strcpy怎么样:

 #include  #include  #include  #define MAX_NAMES 2 int main () { char str[] ="test string."; char *names[MAX_NAMES] = { 0 }; char *test; int i = 0; test = strtok (str," "); while (test != NULL && i < MAX_NAMES) { names[i] = malloc(strlen(test)+1); strcpy(names[i++], test); test = strtok (NULL, " "); } for(i=0; i 

它包含很多杂乱的东西来维护一个完整的程序并清理它的资源,但重点是使用strcpy将每个标记复制到它自己的字符串中。

 #include  #include  #include  char** split(const char *str, const char *delimiter, size_t *len){ char *text, *p, *first, **array; int c; char** ret; *len = 0; text=strdup(str); if(text==NULL) return NULL; for(c=0,p=text;NULL!=(p=strtok(p, delimiter));p=NULL, c++)//count item if(c==0) first=p; //first token top ret=(char**)malloc(sizeof(char*)*c+1);//+1 for NULL if(ret==NULL){ free(text); return NULL; } strcpy(text, str+(first-text));//skip until top token array=ret; for(p=text;NULL!=(p=strtok(p, delimiter));p=NULL){ *array++=p; } *array=NULL; *len=c; return ret; } void free4split(char** sa){ char **array=sa; if(sa!=NULL){ free(array[0]);//for text free(sa); //for array } } int main(void){ char str[] ="test string."; char **words; size_t len=0; int i; words = split(str, " \t\r\n,.", &len); /* for(char **wk = words; *wk ;wk++){ printf("%s\n", *wk); } */ for(i = 0;i 

使用诸如的函数将结果从strtok复制到新缓冲区

 /* * Returns a copy of s in freshly allocated memory. * Exits the process if memory allocation fails. */ char *xstrdup(char const *s) { char *p = malloc(strlen(s) + 1); if (p == NULL) { perror("memory allocation failed"); exit(1); } strcpy(p, s); return p; } 

完成后,不要忘记free返回值。

IMO,你根本不需要(也可能不想)使用strtok (例如,“为此,或其他任何东西”)。 我想我会使用这样的代码:

 #include  #include  static char *make_str(char const *begin, char const *end) { size_t len = end-begin; char *ret = malloc(len+1); if (ret != NULL) { memcpy(ret, begin, len); ret[len]='\0'; } return ret; } size_t tokenize(char *tokens[], size_t max, char const *input, char const *delims) { int i; char const *start=input, *end=start; for (i=0; *start && i 

你也可以这样做。

  int main () { char str[] ="test string."; char * temp1; char * temp2; temp1 = strtok (str," "); temp2 = strchr(str, ' '); if (temp2 != NULL) temp2++; printf ("Splitted string :%s, %s\n" , temp1 , temp2); return }