Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

qsort question 1

Status
Not open for further replies.

bobetko

Programmer
Jan 14, 2003
155
US
Please somebody help
How to use qsort to sort arrays of chars...

Code:
int sproxy(const void* pe1, const void* pe2) {
  return strcmp(*(const char**)pe1,*(const char**)pe2);
}

int main() {
   char mystr[5][50];
   strcpy(mystr[0], "bbbb");
   strcpy(mystr[1], "aaaa");
   strcpy(mystr[2], "cc");
   strcpy(mystr[3], "2222");
   
/* I thought I can send pointer to first element of my array to qsort, but I thoutght wrong. 
Below code doesn't work. Produces Segmential Fault */

   char *sp = &mystr[0][0];       
   qsort(sp,4,sizeof(char*),sproxy);[/b]
}

The way I understand qsort is that qsort will sort pointers to an array, but array itself (in my case mystr) will remain unchanged. Is this correct?
 
Two problems:
1) The element size is incorrect
Code:
   qsort(
      &mystr[0][0],    /* Pointer to first element */
      4,               /* Number of items */
      sizeof(mystr[0]),  /* Size of each element = 50 */
      sproxy);         /* Sort callback */
2) You are dereferencing too much
Code:
int sproxy(const void* pe1, const void* pe2)
{
   const char* str1 = (const char*) pe1;
   const char* str2 = (const char*) pe2;
   return strcmp(str1, str2);
}

The way you handle this varies depending how mystr is defined. The way you did it originally would have worked if you had declared mystr as
Code:
   char* mystr[5];
   mystr[0] = "bbbb";
   mystr[1] = "aaaa";
   mystr[2] = "cc";
   mystr[3] = "2222";
and passed in as
Code:
   qsort(
      &mystr[0],	 // Pointer to first element
      4,		 // Number of items
      sizeof (mystr[0]), // Size of each element = sizeof(char*)
      sproxy);
Note that in both cases, the element size is sizeof(mystr[0]) but the pointer to the first element is different because in the first case it is a 2D array and in the second case it is an array of pointers.
 
Thanks a lot... You saved my day.

Just few more things:
1. I don't really understand how qsort works.
Why this:
Code:
   const char* str1 = (const char*) pe1; 
   const char* str2 = (const char*) pe2;
   return strcmp(str1, str2);
Why didn't I simply return return strcmp(pe1, pe2);.
What's the point of telling that str1 = pe1 and str2 = pe2?

2. For third parameter in qsort I am only supposed to give size od the first element? qsort will know how to do the rest?

3. You said I am dereferencing to much... explain plz.

4. Sorry for lame questions. I am beginner.

Thanks
 
1) It is a lot easier to debug. In the debugger, if you look at str1 and str2, you'll know straight away where you've gone wrong. If say it is a pointer 0x62626262 you're dereferencing too much (one asterisk too many). 0x62 = 'b'. Depends on the debugger. Some are clever enough to understand *((const char**) pe1) but it is a lot to type.

If you want to trace it, you can put down
Code:
printf ("Comparing %s and %s\n", str1, str2);
If it prints anything else other than aaa, bbb etc, you know something has gone wrong.

strcmp takes 2 const char*. If you pass it a const void*, the compiler will moan about it.

2) Yes - it is basically pointer arithmetic. Cast the address of your array to a char and add the size of the first element. Try this with your array.
Code:
   char* str = mystr[0];
   for (i = 0; i < 4; i++)
   {
      printf ("%s\n", str);
      str += sizeof (mystr[0]);
   }
Notice how it does the equivalent of
Code:
   for (i = 0; i < 4; i++)
   {
      printf ("%s\n", mystr[i]);
   }
3) See (1).
4) Don't worry about it - everyone goes through that phase.

When I was in Uni, the only language around that did this sort of dereferencing was BCPL. It took me ages to understand what all these exclamation marks (equivalent of *) were. It took a long time because the academics who used it didn't understand what I did not understand. You need to draw pictures to understand it initially, otherwise it is very abstract.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top