C語言實現strtok與strtok_r
阿新 • • 發佈:2019-01-27
#include <stdio.h> #include <stdlib.h> bool isContained(const char *str, char c) { if (str == NULL) { return false; } const char *p = str; while (*p != '\0') { if (*p == c) { return true; } p++; } return false; } //*save_ptr等價於以前的靜態指標 char *myStrtok_r(char* string_org,const char* demial, char **save_ptr) { char *str = NULL; //返回的字串 const char *ctrl = demial; //分隔符 if (demial == NULL) { return NULL; } if (string_org == NULL && *save_ptr == NULL) { return NULL; } //將分隔符放入map中 char map[255] = {0}; size_t len = 0; while (*ctrl != '\0') { if (isContained(map, *ctrl)) { continue; } map[len] = *ctrl; len++; ctrl++; } if (string_org == NULL) { str = *save_ptr; } else { str = string_org; } //忽略掉字串中起始部分的分隔符,找到第一個不是分隔符的字元指標 while(*str != '\0') { if (isContained(map, *str)) { str++; continue; } break; } string_org = str; //查詢第一個分隔符 while (*str) { if (isContained(map, *str)) { *str++ = '\0'; //當找到時,把匹配字元填為0,並且把str指向下一位 break; } str++; } *save_ptr = str; // 把剩餘字串的指標儲存到靜態變數last if (string_org == str) { *save_ptr = NULL; return NULL; } else { return string_org; } } char *myStrtok(char* string_org,const char* demial) { static char *last = NULL; //保留分割後剩餘的部分 return myStrtok_r(string_org, demial, &last); } int main(void) { /* char str[] = ",.abc,4"; char *demial = ",."; printf("%s\n", myStrtok(str, demial)); printf("%s\n", myStrtok(NULL, demial)); */ int in=0; char buffer[]="Fred male 25,John male 62,Anna female 16"; char *p[20] = {NULL}; //將各個資訊存放到字串陣列中 char *buf=buffer; char *outer_ptr=NULL; char *inner_ptr=NULL; /*while((p[in] = myStrtok(buf, ",")) != NULL) { buf = p[in]; while ((p[in] = myStrtok(buf, " ")) != NULL) { in++; buf = NULL; } buf = NULL; }*/ while((p[in] = myStrtok_r(buf, ",", &outer_ptr)) != NULL) { buf = p[in]; while ((p[in] = myStrtok_r(buf, " ", &inner_ptr)) != NULL) { in++; buf = NULL; } buf = NULL; } printf("Here we have %d strings\n",in); for (int j=0; j<in; j++) { printf(">%s<\n",p[j]); } system("pause"); return 0; } #include <stdlib.h> bool isContained(const char *str, char c) { if (str == NULL) { return false; } const char *p = str; while (*p != '\0') { if (*p == c) { return true; } p++; } return false; } //*save_ptr等價於以前的靜態指標 char *myStrtok_r(char* string_org,const char* demial, char **save_ptr) { char *str = NULL; //返回的字串 const char *ctrl = demial; //分隔符 if (demial == NULL) { return NULL; } if (string_org == NULL && *save_ptr == NULL) { return NULL; } //將分隔符放入map中 char map[255] = {0}; size_t len = 0; while (*ctrl != '\0') { if (isContained(map, *ctrl)) { continue; } map[len] = *ctrl; len++; ctrl++; } if (string_org == NULL) { str = *save_ptr; } else { str = string_org; } //忽略掉字串中起始部分的分隔符,找到第一個不是分隔符的字元指標 while(*str != '\0') { if (isContained(map, *str)) { str++; continue; } break; } string_org = str; //查詢第一個分隔符 while (*str) { if (isContained(map, *str)) { *str++ = '\0'; //當找到時,把匹配字元填為0,並且把str指向下一位 break; } str++; } *save_ptr = str; // 把剩餘字串的指標儲存到靜態變數last if (string_org == str) { *save_ptr = NULL; return NULL; } else { return string_org; } } char *myStrtok(char* string_org,const char* demial) { static char *last = NULL; //保留分割後剩餘的部分 return myStrtok_r(string_org, demial, &last); } int main(void) { /* char str[] = ",.abc,4"; char *demial = ",."; printf("%s\n", myStrtok(str, demial)); printf("%s\n", myStrtok(NULL, demial)); */ int in=0; char buffer[]="Fred male 25,John male 62,Anna female 16"; char *p[20] = {NULL}; //將各個資訊存放到字串陣列中 char *buf=buffer; char *outer_ptr=NULL; char *inner_ptr=NULL; /*while((p[in] = myStrtok(buf, ",")) != NULL) { buf = p[in]; while ((p[in] = myStrtok(buf, " ")) != NULL) { in++; buf = NULL; } buf = NULL; }*/ while((p[in] = myStrtok_r(buf, ",", &outer_ptr)) != NULL) { buf = p[in]; while ((p[in] = myStrtok_r(buf, " ", &inner_ptr)) != NULL) { in++; buf = NULL; } buf = NULL; } printf("Here we have %d strings\n",in); for (int j=0; j<in; j++) { printf(">%s<\n",p[j]); } system("pause"); return 0; }