我需要将C字符串分成标记。我认为strtok将是我最好的尝试,但我得到了非常奇怪的结果......
这是我的测试程序。在这个例子中,我将获得带有“##”分隔符的3个令牌,但是当我尝试使用我认为已复制的那些时,只有第三个正确显示..其他两个看起来已损坏或者某些东西......我不知道知道吗......?
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#define TAM 3 //elements
char** aTokens(char* str, char* delimitador)
{
char* pch;
char** tokens;
int i = 0;
tokens = (char**)malloc(sizeof(char*)*TAM);
pch = strtok(str, delimitador);
while(pch != NULL)
{
tokens[i] = (char*)malloc((sizeof(strlen(pch))+1) * sizeof(char));
strcpy(tokens[i], pch);
pch = strtok(NULL, delimitador);
i++;
}
return tokens;
}
int main ()
{
char str[] = "30117700,1,TITULAR,SIGQAA070,1977/11/30,M,1,14000,0.00,6600.00,10.00,2011/09/01,2012/09/01,0|17,0.00,NO,0,0,0.00, ,##30117700,1,TITULAR,SIGQAA070,1977/11/30,M,1,14000,0.00,6600.00,10.00,2011/09/01,2012/09/01,0|17,0.00,NO,0,0,0.00, ,##30117700,1,TITULAR,SIGQAA070,1977/11/30,M,1,14000,0.00,6600.00,10.00,2011/09/01,2012/09/01,0|17,0.00,NO,0,0,0.00, ,";
char** tokens;
int i;
tokens = aTokens(str, "##");
for(i = 0; i<TAM; i++)
printf("%d -- %s\n", strlen(tokens[i]), tokens[i]);
//Clean
//for(i = 0; i<TAM; i++)
//free(tokens[i]);
//free(tokens);
return 0;
}
在Linux上使用GCC输出:
13 -- 30117700,1,T <---- ?
13 -- 30117700,1,T <----- ?
115 -- 30117700,1,TITULAR,SIGQAA070,1977/11/30,M,1,14000,0.00,6600.00,10.00,2011/09/01,2012/09/01,0|17,0.00,NO,0,0,0.00, ,
我评论过“干净”部分,因为它也提供了很多运行时错误...... :(
请帮助!!
答案 0 :(得分:3)
我认为你对strtok
的工作方式感到有些困惑。
在大多数情况下,你做对了。但是,赋给strtok
的分隔符字符串本身不用作字符串,但它更像是一个字符数组,而strtok
只关心这些单个字符。所以用字符串“#”调用strtok
与给它“##”完全相同。为了正确地标记你的字符串,你需要决定使用一个分隔符,或者使用一个可以处理多字符分隔符的不同(也许是自定义)标记器函数。
答案 1 :(得分:2)
以下行不正确。无论字符串的长度如何,sizeof(strlen(..))
都是4(在32位应用程序中)。
tokens[i] = (char*)malloc((sizeof(strlen(pch))+1) * sizeof(char));
应该是:
tokens[i] = (char*)malloc((strlen(pch)+1) * sizeof(char));
答案 2 :(得分:1)
strtok
的标准实施:
/* strtok example */
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "30117700,1,TITULAR,SIGQAA070,1977/11/30,M,1,14000,0.00,6600.00,10.00,2011/09/01,2012/09/01,0|17,0.00,NO,0,0,0.00, ,##30117700,1,TITULAR,SIGQAA070,1977/11/30,M,1,14000,0.00,6600.00,10.00,2011/09/01,2012/09/01,0|17,0.00,NO,0,0,0.00, ,##30117700,1,TITULAR,SIGQAA070,1977/11/30,M,1,14000,0.00,6600.00,10.00,2011/09/01,2012/09/01,0|17,0.00,NO,0,0,0.00, ,";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str,"#");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, "#");
}
return 0;
}