在C中对字符串进行标记

我一直试图使用SPACE作为分隔符来标记字符串,但它不起作用。 有没有人建议为什么它不起作用?

编辑:使用以下方式标记:

strtok(string, " "); 

代码如下

 pch = strtok (str," "); while (pch != NULL) { printf ("%s\n",pch); pch = strtok (NULL, " "); } 

像这样做:

 char s[256]; strcpy(s, "one two three"); char* token = strtok(s, " "); while (token) { printf("token: %s\n", token); token = strtok(NULL, " "); } 

注意: strtok将字符串修改为其标记,因此它不能是const char*

这是strtok用法的一个例子,请记住strtok对其输入字符串是破坏性的(因此不能在字符串常量上使用)

 char *p = strtok(str, " "); while(p != NULL) { printf("%s\n", p); p = strtok(NULL, " "); } 

基本上需要注意的是,将NULL作为第一个参数传递给strtok告诉它从先前标记的字符串中获取下一个标记。

strtok可能非常危险。 它不是线程安全的。 它的预期用途是在循环中反复调用,传入前一次调用的输出。 strtok函数有一个内部变量,用于存储strtok调用的状态。 这种状态并非每个线程都是唯一的 – 它是全局的。 如果任何其他代码在另一个线程中使用strtok,则会出现问题。 不是你要追查的那种问题!

我建议寻找正则表达式实现,或使用sscanf来拉开字符串。

试试这个:

 char strprint[256]; char text[256]; strcpy(text, "My string to test"); while ( sscanf( text, "%s %s", strprint, text) > 0 ) { printf("token: %s\n", strprint); } 

注意:’text’字符串在分开时被销毁。 这可能不是首选的行为=)

您可以通过引入额外的变量来简化代码。

 #include  #include  int main() { char str[100], *s = str, *t = NULL; strcpy(str, "a space delimited string"); while ((t = strtok(s, " ")) != NULL) { s = NULL; printf(":%s:\n", t); } return 0; } 

我已经制作了一些字符串函数,以便通过尽可能少地使用指针来分割值,因为此代码旨在在PIC18F处理器上运行。 当你有很少的可用内存时,那些处理器不能很好地处理指针:

 #include  #include  char POSTREQ[255] = "pwd=123456&apply=Apply&d1=88&d2=100&pwr=1&mpx=Internal&stmo=Stereo&proc=Processor&cmp=Compressor&ip1=192&ip2=168&ip3=10&ip4=131&gw1=192&gw2=168&gw3=10&gw4=192&pt=80&lic=&A=A"; int findchar(char *string, int Start, char C) { while((string[Start] != 0)) { Start++; if(string[Start] == C) return Start; } return -1; } int findcharn(char *string, int Times, char C) { int i = 0, pos = 0, fnd = 0; while(i < Times) { fnd = findchar(string, pos, C); if(fnd < 0) return -1; if(fnd > 0) pos = fnd; i++; } return fnd; } void mid(char *in, char *out, int start, int end) { int i = 0; int size = end - start; for(i = 0; i < size; i++){ out[i] = in[start + i + 1]; } out[size] = 0; } void getvalue(char *out, int index) { mid(POSTREQ, out, findcharn(POSTREQ, index, '='), (findcharn(POSTREQ, index, '&') - 1)); } void main() { char n_pwd[7]; char n_d1[7]; getvalue(n_d1, 1); printf("Value: %s\n", n_d1); } 

在阅读strtok文档时,我发现在第一次“初始化”调用之后需要传入一个NULL指针。 也许你没有这样做。 只是一个猜测当然。

这是另一个strtok()实现,它能够识别连续的分隔符(标准库的strtok()没有这个)

该函数是BSD许可的字符串库的一部分,称为zString 。 非常欢迎您的贡献:)

https://github.com/fnoyanisi/zString

 char *zstring_strtok(char *str, const char *delim) { static char *static_str=0; /* var to store last address */ int index=0, strlength=0; /* integers for indexes */ int found = 0; /* check if delim is found */ /* delimiter cannot be NULL * if no more char left, return NULL as well */ if (delim==0 || (str == 0 && static_str == 0)) return 0; if (str == 0) str = static_str; /* get length of string */ while(str[strlength]) strlength++; /* find the first occurance of delim */ for (index=0;index 

正如之前的post中所提到的,由于strtok()或我上面提到的那个,依赖于static *char变量来保留连续调用之间的最后一个分隔符的位置,在处理multithreading应用时应该格外小心。

 int not_in_delimiter(char c, char *delim){ while(*delim != '\0'){ if(c == *delim) return 0; delim++; } return 1; } char *token_separater(char *source, char *delimiter, char **last){ char *begin, *next_token; char *sbegin; /*Get the start of the token */ if(source) begin = source; else begin = *last; sbegin = begin; /*Scan through the string till we find character in delimiter. */ while(*begin != '\0' && not_in_delimiter(*begin, delimiter)){ begin++; } /* Check if we have reached at of the string */ if(*begin == '\0') { /* We dont need to come further, hence return NULL*/ *last = NULL; return sbegin; } /* Scan the string till we find a character which is not in delimiter */ next_token = begin; while(next_token != '\0' && !not_in_delimiter(*next_token, delimiter)) { next_token++; } /* If we have not reached at the end of the string */ if(*next_token != '\0'){ *last = next_token--; *next_token = '\0'; return sbegin; } } void main(){ char string[10] = "abcb_dccc"; char delim[10] = "_"; char *token = NULL; char *last = "" ; token = token_separater(string, delim, &last); printf("%s\n", token); while(last){ token = token_separater(NULL, delim, &last); printf("%s\n", token); } 

}

您可以在我的个人资料中提到的博客上阅读详细分析:)