root@ozdaltx.UUCP (root) (02/12/90)
After going over the manuals more times than I'd like, I still can't figure out how to get qsort() (S) to operate. The example shows something like: void qsort(base, nel, width, compar) char *base unsigned nel, width int (*compar)() Is base supposed to be an array? nel & width are self-explanitory What is compar() looking for or how is it assigned? The objective is to sort an array of strings in alpha order and then be able to read them. So far I'm getting is core dumps. Any help, suggestions will be appreciated. thanks Scotty ------ AIDS INFORMATION EXCHANGE BBS (214) 247-2367/247-5609 "Education is the best weapon" {ames,rutgers,texsun,smu}!attctc!ozdaltx!sysop
vp@fctunl.rccn.pt (Vasco Pedro) (02/13/90)
In article <5916@ozdaltx.UUCP> root@ozdaltx.UUCP (root) writes: > > void qsort(base, nel, width, compar) > char *base > unsigned nel, width > int (*compar)() > > Is base supposed to be an array? > nel & width are self-explanitory > What is compar() looking for or how is it assigned? > Yep, 'base' is supposed to the be the (char *)base of the array you intend to sort. 'nel' is the number of elements to be sorted and 'width' the sizeof(element_to_sort). 'compar' is a pointer to int function that must behave like strcmp(s1,s2) a that will be called by qsort(...), for each two elements that will be compared, ie, if elements 2 and 4 need be compared there will be a call of the form: compar(base+(2-1)*width, base+(4-1)*width). If is strings you want to sort might just call (I think): qsort(array,nel,width,strcmp). Sorry for the inaccuracies and hope this helps. -- --- Vasco Pedro BITNET/Internet: vp@host.fctunl.rccn.pt Phone: (+351) (1) 295-4464 (1360) ARPA: vp%hara.fctunl.rccn.pt@mitvma.mit.edu Fax: (+351) (1) 295-4461 PSI/VMS: PSI%(+2680)05010310::HOST::vp UUCP: ...mcvax!inesc!unl!vp Snail: Dept. de Informatica, Universidade Nova de Lisboa 2825 Monte Caparica, PORTUGAL
jha@spodv5.UUCP (Johan Harsta) (02/13/90)
In article <5916@ozdaltx.UUCP>, root@ozdaltx.UUCP (root) writes: > After going over the manuals more times than I'd like, I still can't > figure out how to get qsort() (S) to operate. The example shows > something like: > > void qsort(base, nel, width, compar) > char *base > unsigned nel, width > int (*compar)() > > Is base supposed to be an array? - 'base' should be a pointer to the base of the table, and of type pointer to an element in the table, casted to a pointer to character > nel & width are self-explanitory > What is compar() looking for or how is it assigned? - 'compar' is supplied by you; e.g. 'strcmp' or a modified version of it E.g.: struct ELEMENT buffer[nele]; sort_buf (&buffer[0], nele); void sort_buffer (base, nele) struct ELEMENT *base; int nele; { qsort ((char *) base, (unsigned) nele, (unsigned) sizeof (struct ELEMENT), sorting_alg); return; } int sorting_alg (arg1, arg2) char *arg1; char *arg2; { return (strncmp (arg1, arg2, MAX_RELEVANT_CHARACTERS)); } Something like the above should work, good luck! /Johan Harsta, Programator Uppsala AB, Sweden (consultant for Philips)
gegu@bii.UUCP (Gerhard Gucher) (02/13/90)
In article <5916@ozdaltx.UUCP>, root@ozdaltx.UUCP (root) writes: > After going over the manuals more times than I'd like, I still can't > figure out how to get qsort() (S) to operate. The example shows > something like: > > void qsort(base, nel, width, compar) > char *base > unsigned nel, width > int (*compar)() > > Is base supposed to be an array? > nel & width are self-explanitory > What is compar() looking for or how is it assigned? > > > The objective is to sort an array of strings in alpha order and then > be able to read them. So far I'm getting is core dumps. > qsort is a little bit tricky for arrays of strings. compar() will get the address of two items to be sorted as arguments. Since your arguments are strings (char*'s) you must supply a compare function which accepts (char**)'s as args. The Example has been tested on a SUN OS 4.03 cc compiler. Example: #define NUM_ELEM(a) ( sizeof(a)/sizeof(a[0]) ) /* array to be sorted */ char * array[] = { "beta", "gamma", "alpha", "delta", "epsilon" }; extern int qsort(); /****************************************************************/ int ind_strcmp(s,t) /* indirect string compare for qsort */ char** s; char** t; { return( strcmp(*s,*t) ); } /****************************************************************/ /* ARGSUSED */ int main(argc,argv) int argc; char *argv[]; { int i; (void) qsort( (char*)(&array[0]), NUM_ELEM(array), sizeof(array[0]), ind_strcmp /* gets the address of the char ptrs */ ); /* print the sorted array */ for( i=0; i< NUM_ELEM(array); i++ ) (void)printf( "%s\n", array[i] ); } /* main() */ -- +------------------------------------------------------------------+ | Gerry Gucher uunet!bii!gegu gegu@bii.bruker.com | | Bruker Instruments Inc. Manning Park Billerica MA 01821 | +------------------------------------------------------------------+
david@csource.oz.au (David Nugent) (02/14/90)
> From: root@ozdaltx.UUCP (root) > Date: 12 Feb 90 14:55:54 GMT > Organization: OZ BBS - Dallas, TX > Message-ID: <5916@ozdaltx.UUCP> > > void qsort(base, nel, width, compar) > char *base > unsigned nel, width > int (*compar)() > > Is base supposed to be an array? Yes. > nel & width are self-explanitory > What is compar() looking for or how is it assigned? compar() is the address of a compare function. It's prototype is something like: int compar (char *, char *); > The objective is to sort an array of strings in alpha order > and then > be able to read them. So far I'm getting is core dumps. Well, fortunately strcmp() is compatible with the function. The following should work ok: qsort (base, 20, 64, strcmp); This would sort an array of strings placed in an array of 64 bytes (size of each element), and sort twenty elements into alpha order. david -- UUCP: ...!munnari!csource!david INTERNET: david@csource.oz.au Via FidoNet 3:632/348, Central Source ICBS, Melbourne, Australia
ryan@sjuphil.uucp (Patrick M. Ryan) (02/14/90)
In article <5916@ozdaltx.UUCP> root@ozdaltx.UUCP (root) writes: >After going over the manuals more times than I'd like, I still can't >figure out how to get qsort() (S) to operate. The example shows >something like: > > void qsort(base, nel, width, compar) > char *base > unsigned nel, width > int (*compar)() > >Is base supposed to be an array? >nel & width are self-explanitory >What is compar() looking for or how is it assigned? > >The objective is to sort an array of strings in alpha order and then >be able to read them. So far I'm getting is core dumps. yes, base is supposed to be an array. compar() takes two pointers to structures to compare. compare must return an integer (say, ret) to indicate the order of the two items. ret = 0 if they are equal, ret < 0 if the first item is less than the second, and ret > 1 other wise. ex: #define LEN 32 #define MAX 512 char str[LEN][MAX]; int compare(); main() { . . . qsort(str,MAX,LEN,compare); . . } int compare(s1,s2) char *s1, *s2; { return(strcmp(s1,s2)); } -- patrick m. ryan ryan%sjuphil.sju.edu@bpa.bell-atl.com {bpa|burdvax|princeton|rutgers}!sjuphil!ryan pmr@gemini.gsfc.nasa.gov
root@ozdaltx.UUCP (root) (02/14/90)
Just want to say THANKS TO ALL the many responces I received about qsort(). I know I can always count on the net.gurus to clairify or help with a problem. It is fustrating when the manuals are poorly written without decent examples, seems as if one almost has to know how something works before reading up on it. Too much is assumed by the manual writters. I'll post a summery of responces in the next day or so, maybe someone else will bebefit for it. Scotty ------ AIDS INFORMATION EXCHANGE BBS (214) 247-2367/247-5609 "Education is the best weapon" {ames,rutgers,texsun,smu}!attctc!ozdaltx!sysop
daved@physiol.su.oz (Dave Davey) (02/15/90)
jha@spodv5.UUCP (Johan Harsta) writes: |In article <5916@ozdaltx.UUCP>, root@ozdaltx.UUCP (root) writes: |> After going over the manuals more times than I'd like, I still can't |> figure out how to get qsort() (S) to operate. The example shows |E.g.: | struct ELEMENT buffer[nele]; | sort_buf (&buffer[0], nele); | void | sort_buffer (base, nele) | struct ELEMENT *base; | int nele; | { /*****************************/ int sorting_alg(); /**** needs this declaration */ /*****************************/ | qsort ((char *) base, | (unsigned) nele, | (unsigned) sizeof (struct ELEMENT), | sorting_alg); | return; | }
msb@sq.sq.com (Mark Brader) (02/21/90)
> > void qsort(base, nel, width, compar) > > char *base > > unsigned nel, width > > int (*compar)() > Yep, 'base' is supposed to the be the (char *)base of the array you > intend to sort. 'nel' is the number of elements to be sorted and > 'width' the sizeof(element_to_sort). > 'compar' is a pointer to int function that must behave like strcmp... > If is strings you want to sort might just call (I think): > qsort(array,nel,width,strcmp). This is correct as far as it goes but there is a tricky point that must be emphasized. The compar function that you provide will be called with arguments that *point to* the elements of the array. (It works this way because the array elements might have a type that cannot be passed efficiently, or at all, as a function argument.) Therefore, if you have a 2-dimensional array of chars where each row is used to contain a string, like this: char place[][MAXLEN+1] = {"Portugal", "Canada", "Paraguay", "Japan"}; then you can indeed sort it with #define NUMEL(x) (sizeof x / sizeof *x) int strcmp(); qsort ((char *) place, NUMEL (place), sizeof *place, strcmp); However, if your array itself contains pointers, like this: char *place[] = {"Portugal", "Canada", "Paraguay", "Japan"}; then you must define a function int indstrcmp (sp1, sp2) char *sp1, *sp2; { return strcmp ( * (char **) sp1, * (char **) sp2); } The arguments to indstrcmp() have to be declared as char * rather than char **, and then converted to char **,, because char * is what qsort() is going to pass to indstrcmp(). and invoke qsort using it: qsort ((char *) place, NUMEL (place), sizeof *place, indstrcmp); All of the above is in pre-ANSI style. In ANSI C, void * rather than char * is used as the generic pointer type (but they're represented the same way and passed the same way to functions, so strcmp() will work on void *'s). So the first example becomes: qsort ((void *) place, NUMEL (place), sizeof *place, strcmp); and the second one: int indstrcmp (const void *sp1, const void *sp2) { return strcmp ( * (char **) sp1, * (char **) sp2); } and: qsort ((void *) place, NUMEL (place), sizeof *place, indstrcmp); Followups are directed to comp.lang.c. -- Mark Brader "[This computation] assumed that everything SoftQuad Inc., Toronto would work, a happy state of affairs found utzoo!sq!msb, msb@sq.com only in fiction." -- Tom Clancy This article is in the public domain.