【问题标题】:C strtok ProblemsC strtok 问题
【发布时间】:2018-03-13 18:49:07
【问题描述】:

我有一个链表并试图将其中一个值分成两个不同的变量。我从包含"0000:c29302" 的id 变量开始,但我想将":" 任一侧的部分分解为clientid 和token 变量。 当我运行我的代码时,它会进入 split 函数中的 while 循环,但随后就会崩溃。谢谢!

typedef struct node {
    char *id;
    char *clientid;
    char *token;
    struct node * next;
} credentials;

void split(credentials * head, char *delim);

int main()
{
    credentials * head = NULL;
    head = malloc(sizeof(credentials));

    head->id = "0000:c29302";
    head->next = NULL;
    split(head, ":");
}

void split(credentials * head, char *delim)
{
    char *token;
    char *temp;
    credentials * current = head;
    while (current != NULL) { //THIS WHILE LOOP
        temp = current->id;
        token = strtok(temp, delim);
        while(token != NULL)
        {
            printf("%s\n", token);
            token = strtok(NULL, delim);
        }
        current = current->next;
    }
}

【问题讨论】:

    标签: c linked-list strtok


    【解决方案1】:

    这是因为strtok() 修改了字符串参数!由于您在此处使用字符串文字,因此它很可能保存在您平台上的只读内存中。因此,每次修改它都会导致“Segmentation Violation”。

    如果您确定您的字符串是可修改的,例如使用

    head->id = strdup("0000:c29302");
    

    它应该按预期工作!

    【讨论】:

    • +1 这就是为什么用-Wall 编译很方便。如果您将const char * 分配给char *,我很确定编译器会警告您。
    • @AndrejsCainikovs 在 C 中,字符串文字的类型是 char [] 所以不,这里没有警告
    【解决方案2】:

    查看函数声明时:

    char *strtok(char *str, const char *delim)
    

    您可能会注意到delim 的类型为const char *,但str 的类型为char *。 这是因为此字符串str 的内容被修改并分解为更小的字符串(令牌)

    "0000:c29302" 是字符串文字,内容不能修改。

    任何修改字符串文字的尝试通常都会导致运行时错误"Segmentation Violation".

    您的strtok 必须指向一个可以修改的内存位置。

    因此,您应该为其分配内存并将字符串文字复制到其中。

    您可以使用malloc

    head->id = malloc(strlen("0000:c29302")+1); // 1 char more for string terminator
    strcpy(head->id, "0000:c29302");
    

    或使用char * strdup(const char *str1);

    它返回一个指向空终止字节字符串的指针,它是str1指向的字符串的副本。

    head->id = strdup("0000:c29302");
    

    在这两种情况下,为您的字符串分配的内存必须在某个时候释放以避免内存泄漏。

    【讨论】:

      猜你喜欢
      • 2012-10-16
      • 1970-01-01
      • 2011-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-04
      • 1970-01-01
      相关资源
      最近更新 更多