Thread: I have a char * array that i need to remove duplicates

  1. #1
    Registered User
    Join Date
    May 2016
    Posts
    31

    Post I have a char * array that i need to remove duplicates

    Hi there,

    I have something like:

    Code:
    char * array = { "abc", "def", "ghi", "abc" };
    I want to remove duplicates from this array of pointers. So that "abc" is only mentioned once. How can I accomplish this?

    Thank you.

  2. #2
    Registered User
    Join Date
    Jun 2011
    Posts
    4,508
    To be clear, the code you posted is not an array of pointers, but I get what you're asking.

    Assuming it's a given that all elements point to valid C strings, you want to cycle through the array and compare each value with every subsequent value. Look into the "strcmp" function.

    You also need to determine how you are going to "remove" duplicates - this will depend on the actual declaration.

  3. #3
    Registered User
    Join Date
    May 2016
    Posts
    31
    Dman, thought I had that right haha. Ok well thanks for the clarification. What would you call that array? for future refernece...

    And that sounds about right, I'll give it ago and see how far I get.

    Any more help would be great.

    I just finished making my own reference sheet and theres still stuff believe it or not that I''m wrong on. C is beautiful, but complicated.

    I'd really like to get good with C, so hopefully this board will help me to do that.

    Thanks again for the help!
    Last edited by watchintv; 05-03-2016 at 07:17 PM.

  4. #4
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,739
    What you have there is a compilation error... This is a string array, what you wanted to do:
    Code:
    char* array[] = { "abc", "def", "ghi", "abc" };
    but that also produces a warning, because a string literal( when defined as a pointer and not as a local array ) should always be const.
    So here is the correct version of what you want:
    Code:
    const char* array[] = { "abc", "def", "ghi", "abc" };
    Now that that's taken care of, on to your question, I thought of a simple algorithm to get you started:
    *) Loop through all the strings in that array
    **) If any of the strings is the same as any other after it, turn the second one into a NULL pointer( second inner loop, strcmp() etc )
    **) Ignore any NULL pointers that you encounter further down the array( inside both loops, for good measure )
    *) After the outer loop, you can either move pointers around to pack all those remaining unique strings together, or create a new array for the same reason
    Try to do something similar to that and come back if you have any problems.
    Devoted my life to programming...

  5. #5
    Registered User
    Join Date
    Jun 2011
    Posts
    4,508
    Quote Originally Posted by watchintv View Post
    Dman, thought I had that right haha. Ok well thanks for the clarification. What would you call that array? for future refernece...
    What you posted was just a pointer. GReaper posted a good detailed clarification.

    Quote Originally Posted by watchintv View Post
    And that sounds about right, I'll give it ago and see how far I get.
    Wonderful!

    Quote Originally Posted by watchintv View Post
    Any more help would be great.
    Er, you've received answers to the questions you've asked. Any additional help must be framed from further questions by you.

    Quote Originally Posted by watchintv View Post
    I just finished making my own reference sheet and theres still stuff believe it or not that I''m wrong on. C is beautiful, but complicated.
    Making personal reference sheets is a great thing to do. I still do that to this day when learning something I am not familiar with.

    Quote Originally Posted by watchintv View Post
    I'd really like to get good with C, so hopefully this board will help me to do that.
    You can learn a lot by hanging out here.

  6. #6
    Registered User
    Join Date
    May 2016
    Posts
    31
    Quote Originally Posted by GReaper View Post
    What you have there is a compilation error... This is a string array, what you wanted to do:
    Code:
    char* array[] = { "abc", "def", "ghi", "abc" };
    but that also produces a warning, because a string literal( when defined as a pointer and not as a local array ) should always be const.
    So here is the correct version of what you want:
    Code:
    const char* array[] = { "abc", "def", "ghi", "abc" };
    Now that that's taken care of, on to your question, I thought of a simple algorithm to get you started:


    Try to do something similar to that and come back if you have any problems.
    Ok, well I tried. I totally understand what you mean but I'm having problems implementing it.


    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main() {
    
    
            const char* array[] = { "abc", "def", "ghi", "abc" };
    
            int c;
            for(c = 0; c < sizeof(*array); c++)
            {
    
                    int t;
                    for(t = 0; t < sizeof(*array); t++)
                    {
                            if (strcmp(array[c],array[t]) == 0)
                            {
                                    array[t] = NULL;
                            }
                    }
    
            }
    
    }

  7. #7
    Registered User
    Join Date
    Jun 2011
    Posts
    4,508
    You should explain the problems you're having, along with any errors, warnings, and/or incorrect results.

    Here are some observations on the code you posted:

    • sizeof(*array) does not give you the number of elements in the array. You can use sizeof(array)/sizeof(array[0]), or alternatively, you can use a named constant.
    • "strcmp" expects a valid C string. If your strategy is to "remove" words by setting their pointer to NULL, you should ensure a pointer is not NULL before passing it to "strcmp".
    • There's no reason the inner loop should start at zero. Imagine you were doing the comparison on paper, using your fingers to point to the strings. Your left hand ("c") would point to the first word, and your right hand ("t") would point to the second. Then you move your right hand along the list. When you reach the end, your left hand ("c") moves to the second word, and your right hand ("t") would start at the third. Visualizing the logic this way should give you a clue where to start the inner loop.
    • You should have another loop to print valid strings at the end of the program, so that you can verify the output.


    You should also build your program up gradually, compiling and testing each little bit along the way. A development process

  8. #8
    Registered User
    Join Date
    May 2016
    Posts
    31
    Quote Originally Posted by Matticus View Post
    You should explain the problems you're having, along with any errors, warnings, and/or incorrect results.

    Here are some observations on the code you posted:

    • sizeof(*array) does not give you the number of elements in the array. You can use sizeof(array)/sizeof(array[0]), or alternatively, you can use a named constant.
    • "strcmp" expects a valid C string. If your strategy is to "remove" words by setting their pointer to NULL, you should ensure a pointer is not NULL before passing it to "strcmp".
    • There's no reason the inner loop should start at zero. Imagine you were doing the comparison on paper, using your fingers to point to the strings. Your left hand ("c") would point to the first word, and your right hand ("t") would point to the second. Then you move your right hand along the list. When you reach the end, your left hand ("c") moves to the second word, and your right hand ("t") would start at the third. Visualizing the logic this way should give you a clue where to start the inner loop.
    • You should have another loop to print valid strings at the end of the program, so that you can verify the output.


    You should also build your program up gradually, compiling and testing each little bit along the way. A development process

    Ok, thanks for the tip on array size. What I'm having trouble with is setting up the loops that are required. I understand the logic mostly. Could you post some examples of the loops in question so i can see what you mean. I know its a lot to ask but I don't think I'm gonna understand any of this with out it. I learn best by reading code. Thhnaks.

  9. #9
    Registered User
    Join Date
    Jun 2011
    Posts
    4,508
    Quote Originally Posted by watchintv View Post
    Ok, thanks for the tip on array size. What I'm having trouble with is setting up the loops that are required. I understand the logic mostly. Could you post some examples of the loops in question so i can see what you mean. I know its a lot to ask but I don't think I'm gonna understand any of this with out it. I learn best by reading code. Thhnaks.
    An "example" of the loop logic would basically be a solution, the posting of which goes against the forum guidelines.

    Give it a try and see how far you get. If you get stuck, post your progress and we can go from there.

    If you have specific questions about the logic I suggested above, feel free to ask.

  10. #10
    Registered User
    Join Date
    May 2016
    Posts
    31
    Quote Originally Posted by Matticus View Post
    An "example" of the loop logic would basically be a solution, the posting of which goes against the forum guidelines.

    Give it a try and see how far you get. If you get stuck, post your progress and we can go from there.

    If you have specific questions about the logic I suggested above, feel free to ask.
    Ok, well as it stands right now I have a for loop that cycles through all the strings like so:

    Code:
            int a;
            for (a = 0; a < sizeof(array[0]), a++)
            {
                    printf("%s",array[a]);
    
            }
    From here, I need to implement another loop. That's where I'm confused. Any other guidance?
    Last edited by watchintv; 05-04-2016 at 10:35 AM.

  11. #11
    Registered User
    Join Date
    May 2016
    Posts
    31
    Any chance we could sideline the forum rules this one time and just show me the loop, please. Id really appreciate it.

  12. #12
    Registered User
    Join Date
    Jun 2011
    Posts
    4,508
    Quote Originally Posted by watchintv View Post
    Any chance we could sideline the forum rules this one time and just show me the loop, please. Id really appreciate it.
    Doing so would deprive you of a learning experience, so no, I will not hand you a solution.

    You need to come up with logic before you start writing any code. Get a pencil and paper, and go through the problem "by hand" a few times. Determine the list of steps you need to perform to arrive at a solution. Then use this logical description to develop your code.

    I did not respond to your previous reply because it does not appear to be a genuine attempt - there are some very basic syntax errors in that snippet.

  13. #13
    Registered User
    Join Date
    May 2016
    Posts
    31
    Ok, thanks for the challenge haha. Well, I think I have a solution. Here it is:


    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main() {
    
    
        const char* array[] = { "abc", "def", "def", "ghi", "abc", "abc" };
    
    
        int j;
        for (j = 0; j < sizeof(array)/sizeof(array[0]); j++)
        {
            int k;
            for (k = j + 1; k < sizeof(array)/sizeof(array[0]); k++)
            {        
                if (array[k] != NULL && array[j] != NULL)
                {        
                    if (strcmp(array[j],array[k]) == 0)
                    {
                        array[k] = NULL;
                    }
                }
            }    
        }
    
    
    
        int a;
        for (a = 0; a < sizeof(array)/sizeof(array[0]); a++)
        {
            printf("%s \n",array[a]);
         
        }
    
    
    
    }

  14. #14
    Registered User
    Join Date
    May 2016
    Posts
    31
    Thanks Matticus and GReaper.

  15. #15
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,352
    You forgot to check for null pointers when printing the array elements.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Remove duplicates and save to txt
    By ///André in forum C++ Programming
    Replies: 3
    Last Post: 04-19-2016, 12:44 PM
  2. Two int Arrays, remove duplicates from second
    By Sorin in forum C Programming
    Replies: 5
    Last Post: 04-03-2013, 03:51 AM
  3. Strings and Structs (remove duplicates)
    By christianB in forum C Programming
    Replies: 44
    Last Post: 07-25-2011, 09:01 PM
  4. recursive remove duplicates from a string
    By transgalactic2 in forum C Programming
    Replies: 47
    Last Post: 12-20-2009, 02:02 AM
  5. Really basic remove duplicates from array
    By Chris Fowler in forum C++ Programming
    Replies: 7
    Last Post: 11-25-2002, 10:35 PM

Tags for this Thread