First of all, your sort function (you need only one of them actually), has to be declared as

int mySort(const void * pl, const void * pr)

otherwise it will not compile/work.

The qsort() calls your sort function (which is the brains of the sort) as many times as it deems to be necessary to have your word[] array fully sorted.
You don't have to care about how many times that is, just focus on the fact, that every time your sort function is called (by qsort()), you effectively receive two pointers to a structure of type WORD (the left-hand side and the right-hand-side).

Now, if the left-hand side should be ordered before the right-hand side, return a negative value,
else, if it is vice versa, return a positive value else return zero (i.e. the elements are equal, having same freq count and the strings being equal too). Notice that the semantics of the return value is the same as with strcmp(), which you can use in your sort function.

So, in your one and only sort function, first compare the frequency, if that's equal, let strcmp() do the comparison, else figure out whether to return positive or negative value.

This is the basic construct of your sort function

int mySort(const void * pl, const void * pr)
{
// Get the pointers to the two WORD structs and compare
WORD * pLeft = (WORD *) pl;
WORD * pRight = (WORD *) pr;
// compare here ... left as an excercise ;)
// int result = ...
return result;
}

You need to call qsort() exactly once to have the whole word[] array sorted.

Now provided that you have the following setup:

typedef struct
{
char * word;
int count;
} WORD;
#define MAX_WORDS 123
WORD word[MAX_WORDS] = {0};
size_t wcount = 0;
int main(int argc, char * argv[])
{
// code here to ..
// ... read & parse the input ...

// time to sort the whole word[] array now ...
// Call qsort like shown below!
qsort
(
(void *)word,   // pointer to the start of the array
wcount,           // count of elements placed in the array
sizeof(WORD), // size of a single element to compare
mySort            // pointer to your sort function
);

// At this point your array has been completely sorted

// Print it or whatever you wish to do with it

return 0;
}

"Regarding the checking if the wcount is still less than the MAXWORDS, what output should I make if ever the wcount is still right or vice versa?"

There is no sense in continuing the program if the upper limit has been reached (because there are no means to dynamically grow the word[] array).
So, maybe just output a descriptive error message in that case and exit the program. You can use the exit() function for that purpose.

Will this be enough to check?

if(wcount > MAXWORDS){
exit;
}

Thanks for the tip. I hope I could think of a nice code. Oops I didn't notice it's already 5am here. :|

This is the basic construct of your sort function

int mySort(const void * pl, const void * pr)
{
// Get the pointers to the two WORD structs and compare
WORD * pLeft = (WORD *) pl;
WORD * pRight = (WORD *) pr;
// compare here ... left as an excercise ;)
// int result = ...
return result;
}

Sorry but I can't seem to comprehend those with the pLeft and pNext. Are those temporary variables? And how will I able to access the word[n].count two at a time?

I'd rather use something like

if(MAXWORDS == wcount)
{
printf("Error: maximum number of words (%d) already used. Aborting ...\n", MAXWORDS);
exit(1);
}

In general, whenever your programs fail/exit due to some error condition, try to be informative, so that the user gets some insight on what went wrong (they may be able do something to remedy the situation and retry).

If you have:

WORD * pLeft = (WORD *) pl;

then you use pLeft->count and pLeft->word
and the same way
pRight->count and pRight->word

So you can e.g. compare the words by calling:

strcmp(pLeft->word, pRight->word)

Remember that in the sort function, you only access two individual elements of your word[] array and compare just those two elements (pLeft and pRight) hence telling qsort() how to order these elements. You need/should/must not access your word[] array at all from within your sort function.

You can output the elements inside your sort function by having e.g.

printf("mySort: left argument (%d/%s) - right argument (%d/%s)\n", pLeft->count, pLeft->word, pRight->count, pRight->word);

just to see what gets into your sort function.

>> Are those temporary variables?
Yes, they are just temporary pointers providing access to the actual data.
Maybe names like LeftElemPtr and RightElemPtr would be more descriptive.

One last question before I do the code, what does this initialization WORD * pLeft = (WORD *) pl; means? What's the importance of (WORD *)?

Sorry, I am thinking that my professor might ask me that question. =)

Because pl and pr both are pointers to void, you cannot use them as such to access the data they point to. Hence you need to type cast them properly before usage.
The only correct choice here is to cast them to (WORD *), nothing else will do.

This is the Sort Function I made:

int Sort(const void *l, const void *r)
{
WORD *left = (WORD *) l;
WORD *right = (WORD *) r;
int n;

if(left->count == right->count){
n = strcmp(left->count, right->count);
return n;
} if(left->count > right->count){
return 1;
} else {
return -1;
}
}

Is this function only accessible in the int main() function? Do I really need to place qsort in the main function? The compiler keeps me sending errors that that Sort() is undeclared upon compilation. I am using the cgic.h library, and the cgiMain() there is the counterpart of the int main(). However, in this part, I cannot incorporate any process regarding the sorting, printing stuffs because the cgiMain() primraily takes care of all the cookies, environments, etc. Only one function is incorporated there regarding the whole function of the program, and that's where I am appending all the processes.

int Sort(const void *l, const void *r)
{
WORD *left = (WORD *) l;
WORD *right = (WORD *) r;
int n;

if(left->count == right->count){
n = strcmp(left->count, right->count);
return n;
} if(left->count > right->count){
return 1;
} else {
return -1;
}
}

Your sort function works right out-of-the box, after you have changed:

n = strcmp(left->count, right->count);

to

n = strcmp(left->word, right->word);

Only one function is incorporated there regarding the whole function of the program, and that's where I am appending all the processes.

OK .. then have to insert the qsort() call in that function, just be sure that all the input has been parsed before you call qsort().

That's the problem. The "Sort undeclared" compiler error pops when I place the the sort function there after Parse().

I am trying to figure it out why.

Umm .. that should be easy to solve, I take that you have also declared the Parse() function, so the Sort() function should be declared in same fashion.

When I compile the codes, I get an error saying "Expected expression before int". Do you know what it is?

qsort((void*)word, wcount, sizeof(WORD), int(*Sort)(const void*, const void*));

Change:
qsort((void*)word, wcount, sizeof(WORD), int(*Sort)(const void*, const void*));
to
qsort((void*)word, wcount, sizeof(WORD), Sort);

qsort((void*)word, wcount, sizeof(WORD), Sort);

That is where I get the error "undeclared". Hmm.

You are having a following kind of construct, where the compiler does not know what Sort actually is inside the main() function.

#include <stdlib.h>
// Declaration of Sort commented out
// int Sort(const void *p, const void *p2);
typedef struct
{
int a;
} MYSTRUCT;
MYSTRUCT items[2];
int main(int argc, char* argv[])
{
// Compiler complains "'Sort' : undeclared identifier"
// (rightfully so, because declaration of Sort is commented out, above)
qsort((void *)items, 2, sizeof(MYSTRUCT), Sort);
return 0;
}

int Sort(const void *p, const void *p2)
{
return 0;
}

So you need to declare your Sort() function before the function in which you call qsort().

Sorry it's still the same. =(

Hey you're right! I retyped/reorganized the code and found out that there are two function calls. Then applying your tip, the code now compiles. Gee thanks a lot.

And whoa! My project is almost done, I just have to write the strings into a file.. then it's done! *Hopefully*

At last! I'm done! Thank you mitrmkar! Thanks for being so patient and staying with me. You're really good at this. Keep it up. I am looking forward to return this favor to you someday. Thanks a lot. Hurray!

And now it's time to catch up some sleep. :yawn: