C语言中的嵌套strtok函数问题
我有这样一个字符串:C语言中的嵌套strtok函数问题,c,nested,token,tokenize,strtok,C,Nested,Token,Tokenize,Strtok,我有这样一个字符串: a;b;c;d;e f;g;h;i;j 1;2;3;4;5 我想一个元素一个元素地解析它。我使用了嵌套的strtok函数,但它只拆分第一行,并将null作为令牌指针。我怎样才能克服这个问题?代码如下: token = strtok(str, "\n"); while(token != NULL && *token != EOF) { char a[128], b[128]; strcpy(a,token); strcpy(b,a)
a;b;c;d;e
f;g;h;i;j
1;2;3;4;5
我想一个元素一个元素地解析它。我使用了嵌套的strtok函数,但它只拆分第一行,并将null作为令牌指针。我怎样才能克服这个问题?代码如下:
token = strtok(str, "\n");
while(token != NULL && *token != EOF)
{
char a[128], b[128];
strcpy(a,token);
strcpy(b,a);
printf("a:%s\n",a);
char *token2 = strtok(a,";");
while(token2 != NULL)
{
printf("token2 %s\n",token2);
token2 = strtok(NULL,";");
}
strcpy(token,b);
token = strtok(NULL, "\n");
if(token == NULL)
{
printf("its null");
}
}
输出:
token 2 a
token 2 b
token 2 c
token 2 d
token 2 e
Line: a;b;c;d;e
Token: a
Token: b
Token: c
Token: d
Token: e
Line: f;g;h;i;j
Token: f
Token: g
Token: h
Token: i
Token: j
Line: 1;2;3;4;5
Token: 1
Token: 2
Token: 3
Token: 4
Token: 5
您不能使用
strtok()
;从POSIX或Microsoft(如果有)使用,或重新考虑您的设计
char *strtok_r(char *restrict s, const char *restrict sep,
char **restrict lasts);
char *strtok_s(char *strToken, const char *strDelimit, char **context);
这两个功能可以互换
注意,C11的可选部分中规定了一种变体(ISO/IEC 9899:2011中的附录K)。但是,除了Microsoft之外,很少有供应商实现了标准中该部分的接口。附录K中指定的strtok_s()
版本具有与Microsoft的strtok_s()
不同的接口-类似的问题困扰着附录K中指定的许多其他功能
与strtok_r()
没有strtok_r()
这在上下文中起作用——前提是数据以换行符结尾
#include <string.h>
#include <stdio.h>
int main(void)
{
char data[] = "a;b;c;d;e\nf;g;h;i;j\n1;2;3;4;5\n";
char *string = data;
char *token = strchr(string, '\n');
while (token != NULL)
{
/* String to scan is in string..token */
*token++ = '\0';
printf("a = %s\n", string);
char *token2 = strtok(string, ";");
while (token2 != NULL)
{
printf("b = %s\n", token2);
token2 = strtok(NULL, ";");
}
string = token;
token = strchr(string, '\n');
}
return 0;
}
strtok\u r
是最好、最安全的解决方案,但也有一种方法可以通过strtok
实现:
#include <string.h>
#include <stdio.h>
int main ()
{
char str[] = "a;b;c;d;e\nf;g;h;i;j\n1;2;3;4;5\n";
char *line;
char *token;
char buf[256];
for (line = strtok (str, "\n"); line != NULL;
line = strtok (line + strlen (line) + 1, "\n"))
{
strncpy (buf, line, sizeof (buf));
printf ("Line: %s\n", buf);
for (token = strtok (buf, ";"); token != NULL;
token = strtok (token + strlen (token) + 1, ";"))
{
printf ("\tToken: %s\n", token);
}
}
return 0;
}
你确定你已经读过所有的行了吗?是的,我肯定我读过str。它不适用于我。还有其他解决方案吗?@mausmust:那么你就不走运了——你必须编写自己的解决方案来标记你的字符串,因为
strtok
一次只能处理一个字符串。+1:Devious.for
循环本质上是将strtok()
作为strchr()的组合使用
在找到它的地方加上写NUL'\0'。它之所以有效,是因为您制作并剖析了一个行的副本;否则,您必须调用循环顶部的strlen(line)
,并保存该长度以将其添加到循环控制的第三部分的行中。strtok_r不是最好的,因为它不是C标准(不是C89也不是C99)@user411313:如果可用,它是最好的:-)
a = a;b;c;d;e
b = a
b = b
b = c
b = d
b = e
a = f;g;h;i;j
b = f
b = g
b = h
b = i
b = j
a = 1;2;3;4;5
b = 1
b = 2
b = 3
b = 4
b = 5
#include <string.h>
#include <stdio.h>
int main ()
{
char str[] = "a;b;c;d;e\nf;g;h;i;j\n1;2;3;4;5\n";
char *line;
char *token;
char buf[256];
for (line = strtok (str, "\n"); line != NULL;
line = strtok (line + strlen (line) + 1, "\n"))
{
strncpy (buf, line, sizeof (buf));
printf ("Line: %s\n", buf);
for (token = strtok (buf, ";"); token != NULL;
token = strtok (token + strlen (token) + 1, ";"))
{
printf ("\tToken: %s\n", token);
}
}
return 0;
}
Line: a;b;c;d;e
Token: a
Token: b
Token: c
Token: d
Token: e
Line: f;g;h;i;j
Token: f
Token: g
Token: h
Token: i
Token: j
Line: 1;2;3;4;5
Token: 1
Token: 2
Token: 3
Token: 4
Token: 5