0

I have a function that asks the user for a language, then walks through a linked list of movie structs and prints the movies that have that language. Movies can have multiple language, so the struct's language field has a string that could look like this "[English]" or maybe this "[English;Spanish;Hindi]"

Here is the issue I'm having...The function seems to work as planned. The entered language pulls the desired list. However after the first use of the function, the "token" generated by strtok only always holds "English" regardless of what language one enters. This is probably because "English" is the first entry for every movie's language.

So I'll call the function with a switch statement in a menu function, passing it a pointer to the head of a linked list. I've already verified that every call to the function is still pointing to the head, so I don't think that's the issue.

What I don't understand is why there is different behavior on subsequent function calls. The function exits upon the first call, nothing should remain changed from its previous call, but something must be. I'm thinking it has to do with the "token" pointer for parsing the string, because this is the thing that won't ever not point to English after the first function call.

Here is the function. Any help would be greatly appreciated. This is a school assignment, so it's proper I guess to point me in the right direction rather than fixing the code.

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);
}
dajpearl
  • 1
  • 1

1 Answers1

1

Firstly, you have to allocate enough elements to languageChoice to store strings to read instead of only allocating one elements. It will be like

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

or just

    languageChoice = malloc(1048576);

because sizeof(char) is defined to be 1.

Secondly, strtok will modify the original string, so you should make a copy of original string if you want to preserve that.

Instead of just assigning pointers like

str = list->language;

You should allocate a buffer and copy strings.

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

Then use

free(str);

to free the buffer before moving to the next iteration.

MikeCAT
  • 73,922
  • 11
  • 45
  • 70