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 gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Sorting alphanumeric string

Status
Not open for further replies.

DerPflug

Programmer
Mar 28, 2002
153
US
I have a question before I dive into something futile. Is it possible to sort an array of alphanumeric strings with qsort or will I have to write my own routine? Examples of the strings (which are of fixed length) would be ER1234, GG4576, TY8845, etc.

thanks for any input you can give
 
/*
use can use the internal quick sort, but i find it rather limiting.
Each element of the array must be the same size which limits pointer-
to-character strings.

You also have to prepare your own comparision function.

From man qsort:

void qsort (void *base, size_t nel, size_t width,
int (*compar) (const void *, const void *));

The base argument points to the element at the base of the table. The nel
argument is the number of elements in the table. The width argument is the
size in bytes of each element. The comparison function must return an
integer less than, equal to, or greater than zero, according to whether the
first argument is to be considered as less than, equal to, or greater than the
second argument.


I ran this under SCO Open Server V.

Regards,

Ed
Schaefer

*/
#include <stdio.h>
#include <strings.h>
int comparestr(char *a, char *b);
#define NSTR 3
#define SLEN 8

void main()
{
int i;
char strings [NSTR] [SLEN];

strcpy (strings[0], &quot;TY8845&quot;);
strcpy (strings[1], &quot;GG4576&quot;);
strcpy (strings[2], &quot;ER1234&quot;);

qsort(strings, NSTR, SLEN, comparestr);

for (i=0; i < NSTR; i++)
printf(&quot;%s\n&quot;, strings);

exit(0);
}

/*
* compare strings a and b and return the string
* that's less
*/
int comparestr(a, b)
char *a, *b;
{
return(strcmp(a, b));
}
 
I tried something similar numerous times this afternoon and kept hitting a roadblock. I'm running it in MS Visual C++ and kept getting an error with the compare statement part of qsort, saying that I was comparing a void with pointers or something to that effect, I don't have it in front of me at the moment. I'll definately try your example. Thanks for the help!
 
After running the example I got the following error

C:\Cprograms\qsort_test\qsort_test.cpp(26) : error C2664: 'qsort' :
cannot convert parameter 4 from 'int (char *,char *)' to
'int (__cdecl *)(const void *,const void *)'
None of the functions with this name in scope match the target type

The line that caused the error was the call to qsort. I believe it has something to do with not sending parameters to qsort. Strange, as every resource I've seen says to do it that way. Must be a quirk related to MS Visual Studio.
 
Try changing the signature of the comparison function to something like:

/*
* compare strings a and b and return the string
* that's less
*/
int comparestr(const void *a, const void *b)
{
return(strcmp((char *)a, (char *)b));
}

The following code ran on Win NT4.0 using MSDEV ver6:

Code:
/*----BEGIN----*/
#include <stdio.h>
#include <string.h>    /* for strcmp() */
#include <stdlib.h>    /* for qsort() */


/* new signature */
int comparestr(const void *a,const void *b);

#define NSTR 3
#define SLEN 7      /* was 8 */

void main()
{
int i;
char strings [NSTR] [SLEN];

strcpy (strings[0], &quot;TY8845&quot;);
strcpy (strings[1], &quot;GG4576&quot;);
strcpy (strings[2], &quot;ER1234&quot;);

qsort(strings, NSTR, SLEN, comparestr);

for (i=0; i < NSTR; i++)
   printf(&quot;%s\n&quot;, strings[i]); 

exit(0);
}

/*
 * compare strings a and b and return the string
 * that's less
 */

int comparestr(const void *a, const void *b)
{
	return(strcmp((char *)a, (char *)b));
}

/*----END----*/

NOTE: The comparison function takes 2 args of type `const void *' which you must cast to the type you dealing with.
 
DZH:

I think you're right. The version I submitted over the weekend worked correctly on SCO Open Server V, but failed on Solaris 7 and Red Hat Linux 7.1.

Your compare function worked correctly on both systems.

Interesting.


Regards,


Ed
 
The reason the original code sample failed was because function pointer types must match exactly (return type and number and type of parameters) with the function argument, otherwise you have an illegal conversion.

A few nits on the corrected code:

Since C allows implicit conversions from any pointer type to pointer to void, the casts are unneeded in the strcmp() call above. Though I guess they don't hurt.

The definition of main() is non-standard which reduces the portability of the code and will likely at least produce warnings in modern compilers.
Russ
bobbitts@hotmail.com
 
Thanks for the tip DZH. It works! Thanks to everyone. I've got a C programming project due in one week (with still some hairy parts left) and this was a stick point. Much appreciated.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top