3

I am trying to make program where I have a linked list that has different names of cities + some other irrelevant stuff. City names are, for ex. "Seattle, Boston, New York, Seattle, Washington, Boston". What I am trying to do is make an array that only has unique names of the cities. So for given example, it would be this: "Seattle, Boston, New York, Washington".

My idea was to make a raw array of strings, which would be just the raw data with all the duplicates and then go through each city and make all the other appearances of them "NULL". For some reason, it does not work properly, I have no idea why.

Also, I would appreciate if you guys could help me with your own, easier versions of the solution.

Here is my code:

void city_list(City *head)
{
    City *temp = head;

    char** names_raw;
    char** names_new;
    int num_names = 100;
    int curr_pos = 0;

    names_raw = malloc(num_names * sizeof(char*));

    for(int i = 0; i < num_names; i++)
    {
        names_raw[i] = malloc(256 * sizeof(char));
    }

    while(temp != NULL)
    {
       
        strcpy(names_raw[curr_pos++], temp->name);

        temp = temp->next;
    }

    names_new = malloc(num_names * sizeof(char*));

    for(int i = 0; i < num_names; i++)
    {
        names_new[i] = malloc(256 * sizeof(char));
    }

    for(int i = 0; i < curr_pos; i++)
    {
        if(strcmp(names_raw[i], "NULL"))
        {
            for(int j = i+1; j < curr_pos; j++)
            {
                if(!strcmp(names_raw[j], names_new[i]))
                {
                    strcpy(names_raw[j], "NULL");
                }
            } 

            strcpy(names_new[i], names_raw[i]);
        }
    }

    for(int i = 0; i < curr_pos; i++)
    {
        printf("%s\n", names_new[i]);
    }

    free(names_raw);
    free(names_new);
}

When I debug the code, I don't get any errors, but it prints out all the cities, like nothing was done with the array.

3
  • Well, first things first, you don't really need to copy those strings two times in order to do what you want... do you? Secondly, I hope you are certain that names are shorter than 256 characters, otherwise there are several possibilities of buffer overflow in your code. A safer way of copying would be strncpy(). Commented Jul 13, 2020 at 21:49
  • @MarcoBonelli I do know that those names are shorter than 256 characters but in the assignment that I was given, they explicitly said to use string of maximum 256 characters which I did. Commented Jul 13, 2020 at 22:02
  • 1
    The problem is in the second strcmp, which compares raw[j] to new[i]. There's nothing in new[i] at that point in the code. Once you've fixed that, the next problem is the strcpy that copies raw[i] into new[i]. That should be copying raw[i] into new[k]. Commented Jul 13, 2020 at 22:18

1 Answer 1

0

You've not shown us a complete example (What is "City"? How is your input array built? Etc etc). But I suspect you're making things over-complicated :(

SUGGESTION:

  1. Pass your array into a function named int delete_dupes(char* arr[], int n) (or similar)

  2. Sort the array:

    EXAMPLE CODE: https://www.geeksforgeeks.org/c-program-sort-array-names-strings/

  3. "Delete" the duplicates by moving them to the front of your array

    int delete_dupes(char* arr[], int n) {
      char *current_name = arr[0];
      int i=1, j=1;
      while (i < n) {
        if (strcmp(arr[i], current_name) != 0) {
          free(arr[j]);  /* Do *NOT* do this if you didn't malloc() this string!!!! */
          arr[j++] = arr[i];
          current_name = array[i];
        }
      }
      return j;
    }
    
  4. The function returns the new #/strings. That number will be <= n.

    Additionally, you may want to null out the unused array elements and/or free the duplicate string values.

  5. An "ideal" solution would be for you to implement a dynamic list.

  6. If you want to "malloc()" each string individually, please consider the standard C library function strdup() .

And no, I haven't tested :)

Sign up to request clarification or add additional context in comments.

2 Comments

strcpy won't do what you want if the cities aren't all in same-sized buffers. But you don't even need strcpy; you can just assign directly (and make sure to free overwritten elements if necessary)
Good point - example modified. But not compiled or tested ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.