strtok()的用法

时间:2017-01-07 00:04:19

标签: c strtok

我尝试了insertItem()列表api成功插入所有类型的项目,例如字符串(下方),

static void copyData(List *records, char *delim, char *argv[]){

char *item = malloc(5);
    strcpy(item, "abcd");
    int count = 0;
    while(count++ < 10){

      insertItem(records, item);

      item = malloc(5);
      strcpy(item, "efgh");
    }
}

输出:

$ ./frequencyCounter.exe ARRAY
Key is:abcd
Key is:efgh
Key is:efgh
Key is:efgh
Key is:efgh
Key is:efgh
Key is:efgh
Key is:efgh
Key is:efgh
Key is:efgh
Size of list: 10
Before freeList()After freeList()

strtok()令牌会显示问题代码,如下所示,上面不需要buf[]参数,

static void copyData(List *records, char buf[], char *delim, char *argv[]){

  char *token =  strtok(buf, delim);

  void *item = malloc(strlen(token) + 1);
  item = memcpy(item, token, strlen(token)+1);
    printf("token-%s\n", token);        
  while(token != NULL){

    insertItem(records, item);
    token = strtok(NULL, delim);
    if(token != NULL){
      printf("token-%s\n", token);        
      item = malloc(strlen(token) + 1); //every item has its own heap memory
      memcpy(item, token, strlen(token)+1);
    }
  }

}

输出是,

$ ./frequencyCounter.exe ARRAY
token-it
token-was
token-the
token-best
token-of
token-times
Key is:it
Key is:it
Key is:it
Key is:it
Key is:it
Key is:it
Size of list: 6
Aborted (core dumped)

在问题代码(上图)中,我们可以重复使用strtok()的结果吗?

1 个答案:

答案 0 :(得分:3)

虽然很难理解或阅读您的代码,但以下内容看起来很糟糕

item = malloc(strlen(token));

然后你memcpy() strlen(token) + 1个字节。

这将导致未定义的行为,因此您的程序将表现不正常。

此外,不要过度使用strlen()每次调用它时都会遍历输入字符串的所有字符,而只是将结果存储在某处,如果您需要多次使用它。

这是您的功能的改进版本

static void 
copyData(List *records, char buf[], char *delim, char *argv[])
{
    char *token;
    size_t length;
    void *item;

    token = strtok(buf, delim);
    if (token == NULL)
        return;
    length = strlen(token);
    item = malloc(length + 1);
    if (item == NULL)
        return;
    memcpy(item, token, length + 1);

    printf("token-%s\n", token);        
    while (token != NULL) {
        insertItem(records, item);

        token = strtok(NULL, delim);
        if (token != NULL) {
            length = strlen(token);

            item = malloc(length + 1); // every item has its own heap memory
            if (item != NULL) {
                memcpy(item, token, length + 1);
            }
            printf("token-%s\n", token);
        }
    }
    // Some day, you will have to free these pointers
}

但是我希望它不仅仅是这样,因为item malloc() free strdup()永远不会Map d,因为它在某种程度上违反了DRY原则。还有一件事,你也可以使用TreeMap