【问题标题】:Assigning strtok token to array in struct将strtok令牌分配给struct中的数组
【发布时间】:2015-02-21 00:38:44
【问题描述】:

如何将strtok() 中的值分配给结构中的数组?在我的结构中,我有char *extraRoomOne,而在我的主体中,我有:

while (token!= NULL)
{ 
    token = strtok(NULL, " ");
    certainRoom.extraRoomOne[counter] = token;
}

编译器告诉我取消引用它,但是当我这样做时,我得到一个段错误。

typedef struct room{
    char *extraRoomOne;
}room;

总的来说,我只有 `room certainRoom;

编辑:将 char *extraRoomOne 更改为 char **extraRoomOne

现在我有:

token = strtok(NULL," ");
certainRoom.extraRoomOne = realloc(certainRoom.extraRoomOne,(counter + 1) * sizeof(char *)); 
certainRoom.extraRoomOne[counter] = malloc(strlen(token)+1);         
strcpy(certainRoom.extraRoomOne[counter],token);`

这是realloc和malloc的正确方式吗?我每次也会增加下面的计数器

【问题讨论】:

  • 能否请您出示certainRoom 的声明以及struct 的定义。
  • 最有可能的是,您应该使用strcpy()strdup() 而不是直接赋值,具体取决于您之前是否为extraRoomOne 分配了指向空间。
  • 还有certainRoom?它是一个数组吗?它只是struct room 的一个实例吗?
  • 是struct room的一个实例
  • 你想做什么?因为显然你想捕获许多令牌,那么你想如何存储它们?。

标签: c pointers struct strtok


【解决方案1】:

你不应该做那个赋值,因为strtok()返回一个指向你在第一次调用中传递的字符串的指针,它会在后续调用中改变它,并且'\0'终止符可以被strtok()移动,所以指针最后将指向不同的字符串,但您可以先复制字符串,然后使用malloc() 为其分配空间,然后使用strcpy()

size_t length;

length                   = strlen(token);
certainRoom.extraRoomOne = malloc(1 + length);
if (certainRoom.extraRoomOne != NULL)
    strcpy(certainRoom.extraRoomOne, token);

你应该记得包含string.h

如果您真正想要捕获的不仅仅是一个令牌,这可以解释while 循环,您可以这样做

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

typedef struct room{
    char **tokens;
    size_t count;
} room;

room
tokenizeString(char *string)
{
    char *token;
    room  instance;

    instance.tokens = NULL;
    instance.count        = 0;
    token                    = strtok(string, " ");
    while (token != NULL)
    {
        void  *pointer;
        size_t length;

        pointer = realloc(instance.tokens, (1 + instance.count) * sizeof(char *));
        if (pointer == NULL)
        {
            size_t i;

            for (i = 0 ; i < instance.count ; ++i)
                free(instance.tokens[i]);
            free(instance.tokens);

            instance.tokens = NULL;
            instance.count  = 0;

            return instance;
        }
        instance.tokens                 = pointer;
        length                          = strlen(token);
        instance.tokens[instance.count] = malloc(1 + length);
        if (instance.tokens[instance.count] != NULL)
            strcpy(instance.tokens[instance.count], token);
        instance.count += 1;
        token           = strtok(NULL, " ");
    }
    return instance;
}

int
main(int argc, char **argv)
{
    room   certainRoom;
    size_t i;

    if (argc < 1) /* invalid number of arguments */
        return -1;
    certainRoom = tokenizeString(argv[1]);
    for (i = 0 ; i < certainRoom.count ; ++i)
    {
        printf("%s\n", certainRoom.tokens[i]);
        /* we are done working with this token, release it */
        free(certainRoom.tokens[i]);
    }
    /* all tokens where released, now released the main container,
     * note, that this only contained the pointers, the data was
     * in the space pointed to by these pointers. */
    free(certainRoom.tokens);

    return 0;
}

【讨论】:

  • 我在复制之前尝试了 realloc,malloc 但现在我遇到了段错误,你能检查一下我做得对吗?我在上面编辑了它
  • @BeginnerC96 使用我建议的代码,因为这样做x = realloc(x, newSize); 是不好的做法,realloc() 指向不同的指针,这样您就可以处理失败,并且不要忽略 malloc() 的返回值.虽然,SIGSEGV 可能是由其他原因引起的,但这取决于字符串的大小,或者在对字符串进行标记后如何使用标记。
猜你喜欢
  • 2019-02-07
  • 1970-01-01
  • 2014-02-13
  • 2015-12-14
  • 2012-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多