C函数在后续调用中具有不同的行为涉及strtok和定界符,指针

问题描述

我有一个功能,要求用户提供一种语言,然后遍历电影结构的链接列表并打印具有该语言的电影。电影可以具有多种语言,因此结构的语言字段中的字符串可能看起来像“ [English]”或“ [English; Spanish; hindi]”

这是我遇到的问题...该功能似乎按计划工作。输入的语言将拉出所需的列表。但是,在首次使用该功能后,无论使用哪种语言输入,strtok生成的“令牌”始终始终保留“英语”。这可能是因为“英语”是每种电影语言的第一项。

因此,我将在菜单函数中使用switch语句调用函数,并向其传递指向链接列表开头的指针。我已经验证了对函数的每次调用仍然指向头部,所以我认为这不是问题。

我不明白的是为什么随后的函数调用会有不同的行为。该函数在第一次调用退出,与其先前的调用相比,什么都应该保持不变,但是必须有所改变。我认为它与解析字符串的“令牌”指针有关,因为在第一个函数调用之后,这永远不会指向英语。

这是功能。任何帮助将不胜感激。这是学校的作业,所以我想向我指出正确的方向,而不是固定代码

void displayByLanguage(struct movie *list,int size)
{
    char *languageChoice;

    languageChoice = malloc(sizeof(char));
    printf("enter a language\n");
    scanf("%s",languageChoice);

    printf("language choice: ");
    printf("%s\n",languageChoice);

    char* str;

    char Delimit[] = ";[] ";
    char* token; 


    while (list != NULL)
    {
        str = list->language;

        token = strtok(str,Delimit); //citation: https://stackoverflow.com/questions/38380419/splitting-a-string-using-multiple-delimiters-in-c
        

        while (token != NULL)
        {
            

            if (strcmp(token,languageChoice) == 0)
            {
                printf("%d: ",list->year);
                printf("%s\n",list->title);
                token = strtok(NULL,Delimit);
            }
            else
            {
                token = strtok(NULL,Delimit); 
            }
        }

        list = list->next;
    }
   
   
    free(languageChoice);
}

解决方法

首先,您必须为languageChoice分配足够的元素以存储要读取的字符串,而不是仅分配一个元素。 就像

    languageChoice = malloc(sizeof(char) * 1048576);

或者只是

    languageChoice = malloc(1048576);

因为sizeof(char)被定义为1

第二,strtok将修改原始字符串,因此,如果要保留原始字符串,则应复制原始字符串。

不仅仅是分配像这样的指针

str = list->language;

您应该分配一个缓冲区并复制字符串。

str = malloc(strlen(list->language) + 1);
strcpy(str,list->language);

然后使用

free(str);

在下一次迭代之前释放缓冲区。