从strtok复制字符串

时间:2011-07-25 18:58:27

标签: c

我需要将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, ,

我评论过“干净”部分,因为它也提供了很多运行时错误...... :(

请帮助!!

3 个答案:

答案 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;
}