如何在C中按
'&'
拆分字符串为标记?char *token;
char *state;
for (token = strtok_r(input, "&", &state);
token != NULL;
token = strtok_r(NULL, "&", &state))
{
...
}
strchr()
):#include <string.h>
char *data = "this&&that&other";
char *next;
char *curr = data;
while ((next = strchr(curr, '&')) != NULL) {
/* process curr to next-1 */
curr = next + 1;
}
/* process the remaining string (the last token) */
strchr(const char *s, int c)
函数返回指向s
中下一个出现c
的位置的指针,如果c
在s
中未找到,则返回NULL
。
你可能可以使用strtok()
,但我不喜欢strtok()
,因为:
"a&&b&c"
,返回的标记是"a"
、"b"
和"c"
。请注意,在"a"
之后没有空标记。strtok()
确实修改了参数字符串 - 分隔符字符被替换为'\0',以便返回的字符串得到正确的终止。 - cafstrtok
必须修改字符串。根据C标准:如果找到这样的字符,则将其覆盖为空字符,从而终止当前令牌。这非常明确。http://opengroup.org/onlinepubs/009695399/functions/strtok.html。你能发一下`strtok()`不修改字符串的代码吗? - Alok Singhal&
拆分字符串。例如,你怎么能单独获取第一个标记 this
。 - nikk wong/// Function to parse a string in separate tokens
int parse_string(char pInputString[MAX_STRING_LENGTH],char *Delimiter,
char *pToken[MAX_TOKENS])
{
int i;
i = 0;
pToken[i] = strtok(pInputString, Delimiter);
i++;
while ((pToken[i] = strtok(NULL, Delimiter)) != NULL){
i++;
}
return i;
}
/// The array pTokens[] now contains the pointers to the start of each token in the (unchanged) original string.
sprintf(String,"Token1&Token2");
NrOfParameters = parse_string(String,"&",pTokens);
sprintf("%s, %s",pToken[0],pToken[1]);
strtok()
函数不直观且过于复杂,因此我设法自己创建了一个函数。它接受一个要分割的字符串作为参数,还有一个用于确定标记之间空格的字符和表示找到的标记数量的指针(在循环中打印这些标记时非常有用)。该函数的一个缺点是每个标记的最大长度是固定的。#include <stdlib.h>
#include <string.h>
#define MAX_WORD_LEN 32
char **txtspt(const char *text, char split_char, int *w_count)
{
if(strlen(text) <= 1)
return NULL;
char **cpy0 = NULL;
int i, j = 0, k = 0, words = 1;
//Words counting
for(i = 0; i < strlen(text); ++i)
{
if(text[i] == split_char && text[i + 1] != '\0')
{
++words;
}
}
//Memory reservation
cpy0 = (char **) malloc(strlen(text) * words);
for(i = 0; i < words; ++i)
{
cpy0[i] = (char *) malloc(MAX_WORD_LEN);
}
//Splitting
for(i = 0; i < strlen(text) + 1; ++i)
{
if(text[i] == split_char)
{
cpy0[k++][j] = '\0';
j = 0;
}
else
{
if(text[i] != '\n') //Helpful, when using fgets()
cpy0[k][j++] = text[i]; //function
}
}
*w_count = words;
return cpy0;
}
char str[] = "&a&&b&c"; // a mutable string
for (char *cp = str; (cp = strtok(cp, "&")) != NULL; cp = NULL) {
/* do something with the token */
}
这里只有一个对 strtok()
的调用,一个分隔符字符串的实例,而且 cp
的作用域仅限于这个循环内。
建议使用 strchr()
并没有考虑到多个分隔符字符。如果建议使用 strcspn()
可能会更好。而且请注意,最后一个标记必须在循环结束后处理。设计不太好...
strtok()
的一个优点是标记已经被隔离在它们当前的位置。如果它们的地址被保存在一个指针数组中,它们可以被重复使用,而不需要一遍又一遍地隔离它们。
&a&&b&c
是否应该像strtok()
(或更好的strtok_r()
)一样分成3部分,或者像strchr()
一样分成5部分,包括2个空字符串,这取决于规范的问题。对于这个问题,问题本身相当模糊:其他语言中可用的split
方法更倾向于后者,而tokens
则更倾向于前者。不过,OP现在肯定比12年前更了解情况了。使用具有相同好特性的strtok_r
的替代方法似乎更可取,尽管它不是标准的。 - undefinedstrchr()
答案有一些问题。而且,“double strtok()”答案也有它自己的问题(如果你明白我的意思的话 :-)... 看到这个问题,我想提供我更喜欢的版本... 不幸的是,我没有
strtok_r()... 也许这是个周末的项目!!
:-)` - undefined
char *strtok_r(char *s, const char *delim, char **context) {
char *token = NULL;
if (s == NULL)
s = *context;
/* 跳过初始的分隔符 */
s += strspn(s, delim);
if (*s != '\0') {
/* 我们有一个标记 */
token = s;
/* 跳过标记 */
s += strcspn(s, delim);
if (*s != '\0') {
/* 切断字符串以终止标记 */
*s++ = '\0';
}
}
*context = s;
return token;
}```
- undefined:-)
- undefined