Hi there,
I have something like:
I want to remove duplicates from this array of pointers. So that "abc" is only mentioned once. How can I accomplish this?Code:char * array = { "abc", "def", "ghi", "abc" };
Thank you.
Hi there,
I have something like:
I want to remove duplicates from this array of pointers. So that "abc" is only mentioned once. How can I accomplish this?Code:char * array = { "abc", "def", "ghi", "abc" };
Thank you.
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.
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.
What you have there is a compilation error... This is a string array, what you wanted to do:
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.Code:char* array[] = { "abc", "def", "ghi", "abc" };
So here is the correct version of what you want:
Now that that's taken care of, on to your question, I thought of a simple algorithm to get you started:Code:const char* array[] = { "abc", "def", "ghi", "abc" };
Try to do something similar to that and come back if you have any problems.*) 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
Devoted my life to programming...
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; } } } }
What you posted was just a pointer. GReaper posted a good detailed clarification.
Wonderful!
Er, you've received answers to the questions you've asked. Any additional help must be framed from further questions by you.
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.
You can learn a lot by hanging out here.
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.
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.
Last edited by watchintv; 05-04-2016 at 10:35 AM.
Any chance we could sideline the forum rules this one time and just show me the loop, please. Id really appreciate it.
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]); } }
Thanks Matticus and GReaper.
You forgot to check for null pointers when printing the array elements.
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
j should only run to the array size -1.Code:for (j = 0; j < sizeof(array)/sizeof(array[0]); j++)
Because, if j is the last index, there is no member behind it to check.
should be:
In the inner loop, you check if member j points to NULL, very good.Code:for (j = 0; j < (sizeof(array) / sizeof(array[0]) - 1); j++)
But is it NULL, you run the rest of the array with k.
You can check it before k is run.
Directly in the outer loop:
Line 16 and 18 are both if-statements. You can compine it.Code:if (array[j] != NULL) { int k; … }
Now that we know that array[j] isn't NULL, we come to the resulting if-statement:
Also please fix what laserlight says. I let you find out by your self, because it is very simple.Code:if (array[k] != NULL && strcmp(array[j], array[k]) == 0)
All in all, nice work! Great job. Good formated and indented source, nice.
Last edited by WoodSTokk; 05-05-2016 at 07:03 AM.
Other have classes, we are class