473,388 Members | 1,234 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,388 software developers and data experts.

How would I use qsort to sort a struct with a char* member and a long member - I want to sort in order of the long member

Hello

Here is my code so far. Is this correct/incorrect/along the right
lines/other?

#include <stdio.h>
#include <string.h>
#include <search.h>
struct mystruct
{
long nKey;
char szIP[20];
};

int compare( const void *long1, const void *long2 );

int main()
{
mystruct devlist[4];
devlist[0].nKey = 9;
strcpy(devlist[0].szIP, "192.168.1.1");
devlist[1].nKey = 2;
strcpy(devlist[1].szIP, "192.168.1.2");
devlist[2].nKey = 7;
strcpy(devlist[2].szIP, "192.168.1.3");
devlist[3].nKey = 1;
strcpy(devlist[3].szIP, "192.168.1.4");
qsort( (void *)devlist, (size_t)4, sizeof( char * ), compare );

// bsearch is the next thing to work out how to do!
// void *bsearch( const void *key, const void *base, size_t num, size_t
width, int
// ( __cdecl *compare ) ( const void *elem1, const void *elem2 ) );
return 0;
}

int compare( const void* val1, const void* val2 )
{
struct mystruct *sp1 = (mystruct*)val1;
struct mystruct *sp2 = (mystruct*)val2;
// IS THIS CORRECT?
return (int)(sp1->nKey - sp2->nKey);
}

Angus Comber
an***@NOSPAMiteloffice.com
Nov 14 '05 #1
7 5271
On Thu, 5 Feb 2004 14:43:22 -0000, "Angus Comber"
<an***@iteloffice.com.PLEASENOSPAM> wrote:
Please use a short subject line, and put the complete text of your
question in the message body.

#include <stdio.h>
#include <string.h>
#include <search.h>
struct mystruct
{
long nKey;
char szIP[20];
};
So is this C or C++? If C++, fine. If C, in order to use "mystruct" as
a typename (without having to say "struct mystruct", add this:

typedef struct mystruct mystruct;

int compare( const void *long1, const void *long2 );

int main()
{
mystruct devlist[4];
To do the above in C, add the aforementioned typedef.
devlist[0].nKey = 9;
strcpy(devlist[0].szIP, "192.168.1.1");
devlist[1].nKey = 2;
strcpy(devlist[1].szIP, "192.168.1.2");
devlist[2].nKey = 7;
strcpy(devlist[2].szIP, "192.168.1.3");
devlist[3].nKey = 1;
strcpy(devlist[3].szIP, "192.168.1.4");
qsort( (void *)devlist, (size_t)4, sizeof( char * ), compare );

// bsearch is the next thing to work out how to do!
// void *bsearch( const void *key, const void *base, size_t num, size_t
width, int
// ( __cdecl *compare ) ( const void *elem1, const void *elem2 ) );
return 0;
}

int compare( const void* val1, const void* val2 )
{
struct mystruct *sp1 = (mystruct*)val1;
struct mystruct *sp2 = (mystruct*)val2;
// IS THIS CORRECT?
return (int)(sp1->nKey - sp2->nKey);
If you want to sort in descending order, yes. If you want to sort in
_ascending_ order, flip the operands around.

Overall, a good first stab if you've never used qsort before.

Have fun,
-leor
}


Leor Zolman
BD Software
le**@bdsoft.com
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html
Nov 14 '05 #2
Hello

Thanks for that. I am using VC++ so it didn't complain at the mystruct
line!

However, real reason for replying is that on first call of compare function,
if I do this:

struct mystruct *sp1 = (mystruct*)val1;
struct mystruct *sp2 = (mystruct*)val2;
sp1->nKey is some wierd value - 775043377
sp2->nKey is 9

on the second call to compare the values are:
sp1->nKey is some wierd value - 775435825
sp2->nKey is 775043377

So I have definitely done something wrong!

Any ideas?

"Leor Zolman" <le**@bdsoft.com> wrote in message
news:58********************************@4ax.com...
On Thu, 5 Feb 2004 14:43:22 -0000, "Angus Comber"
<an***@iteloffice.com.PLEASENOSPAM> wrote:
Please use a short subject line, and put the complete text of your
question in the message body.

#include <stdio.h>
#include <string.h>
#include <search.h>
struct mystruct
{
long nKey;
char szIP[20];
};


So is this C or C++? If C++, fine. If C, in order to use "mystruct" as
a typename (without having to say "struct mystruct", add this:

typedef struct mystruct mystruct;

int compare( const void *long1, const void *long2 );

int main()
{
mystruct devlist[4];


To do the above in C, add the aforementioned typedef.
devlist[0].nKey = 9;
strcpy(devlist[0].szIP, "192.168.1.1");
devlist[1].nKey = 2;
strcpy(devlist[1].szIP, "192.168.1.2");
devlist[2].nKey = 7;
strcpy(devlist[2].szIP, "192.168.1.3");
devlist[3].nKey = 1;
strcpy(devlist[3].szIP, "192.168.1.4");
qsort( (void *)devlist, (size_t)4, sizeof( char * ), compare );

// bsearch is the next thing to work out how to do!
// void *bsearch( const void *key, const void *base, size_t num, size_t
width, int
// ( __cdecl *compare ) ( const void *elem1, const void *elem2 ) );
return 0;
}

int compare( const void* val1, const void* val2 )
{
struct mystruct *sp1 = (mystruct*)val1;
struct mystruct *sp2 = (mystruct*)val2;
// IS THIS CORRECT?
return (int)(sp1->nKey - sp2->nKey);


If you want to sort in descending order, yes. If you want to sort in
_ascending_ order, flip the operands around.

Overall, a good first stab if you've never used qsort before.

Have fun,
-leor
}


Leor Zolman
BD Software
le**@bdsoft.com
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html

Nov 14 '05 #3
On Thu, 5 Feb 2004 15:27:38 -0000, "Angus Comber"
<an***@iteloffice.com.PLEASENOSPAM> wrote:
Hello

Thanks for that. I am using VC++ so it didn't complain at the mystruct
line!

However, real reason for replying is that on first call of compare function,
if I do this:

struct mystruct *sp1 = (mystruct*)val1;
struct mystruct *sp2 = (mystruct*)val2;
sp1->nKey is some wierd value - 775043377
sp2->nKey is 9

on the second call to compare the values are:
sp1->nKey is some wierd value - 775435825
sp2->nKey is 775043377

So I have definitely done something wrong!
Sorry, my bad. I just ran it, it worked, and I didn't look hard enough
at the ordering...it was actually not in descending order.

Here's the problem: in your qsort call:

qsort( (void *)devlist, (size_t)4, sizeof( char * ), compare);

the 3rd parameter should be
sizeof (mystruct)
instead of
sizeof (char *)

I failed to double-check against my own mental checklist for args to
qsort:
"base, nel, width, compare"
-leor

Any ideas?

"Leor Zolman" <le**@bdsoft.com> wrote in message
news:58********************************@4ax.com.. .
On Thu, 5 Feb 2004 14:43:22 -0000, "Angus Comber"
<an***@iteloffice.com.PLEASENOSPAM> wrote:
Please use a short subject line, and put the complete text of your
question in the message body.
>
>#include <stdio.h>
>#include <string.h>
>#include <search.h>
>struct mystruct
>{
> long nKey;
> char szIP[20];
>};


So is this C or C++? If C++, fine. If C, in order to use "mystruct" as
a typename (without having to say "struct mystruct", add this:

typedef struct mystruct mystruct;
>
>int compare( const void *long1, const void *long2 );
>
>int main()
>{
> mystruct devlist[4];


To do the above in C, add the aforementioned typedef.
> devlist[0].nKey = 9;
> strcpy(devlist[0].szIP, "192.168.1.1");
> devlist[1].nKey = 2;
> strcpy(devlist[1].szIP, "192.168.1.2");
> devlist[2].nKey = 7;
> strcpy(devlist[2].szIP, "192.168.1.3");
> devlist[3].nKey = 1;
> strcpy(devlist[3].szIP, "192.168.1.4");
> qsort( (void *)devlist, (size_t)4, sizeof( char * ), compare );
>
> // bsearch is the next thing to work out how to do!
> // void *bsearch( const void *key, const void *base, size_t num, size_t
>width, int
> // ( __cdecl *compare ) ( const void *elem1, const void *elem2 ) );
> return 0;
>}
>
>int compare( const void* val1, const void* val2 )
>{
> struct mystruct *sp1 = (mystruct*)val1;
> struct mystruct *sp2 = (mystruct*)val2;
> // IS THIS CORRECT?
> return (int)(sp1->nKey - sp2->nKey);


If you want to sort in descending order, yes. If you want to sort in
_ascending_ order, flip the operands around.

Overall, a good first stab if you've never used qsort before.

Have fun,
-leor
>}


Leor Zolman
BD Software
le**@bdsoft.com
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html


Leor Zolman
BD Software
le**@bdsoft.com
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html
Nov 14 '05 #4


Angus Comber wrote:
Hello

Here is my code so far. Is this correct/incorrect/along the right
lines/other?

You are on the right tract but have a few errors.
#include <stdio.h>
#include <string.h>
#include <search.h>
search.h is not a Standard C header file. To declare functions qsort
and bsearch use the header stdlib.h
Replace the search.h include with
#include <stdlib.h>
struct mystruct
{
long nKey;
char szIP[20];
};

int compare( const void *long1, const void *long2 );

int main()
{
mystruct devlist[4]; struct mystruct devlist[4]; devlist[0].nKey = 9;
strcpy(devlist[0].szIP, "192.168.1.1");
devlist[1].nKey = 2;
strcpy(devlist[1].szIP, "192.168.1.2");
devlist[2].nKey = 7;
strcpy(devlist[2].szIP, "192.168.1.3");
devlist[3].nKey = 1;
strcpy(devlist[3].szIP, "192.168.1.4");
qsort( (void *)devlist, (size_t)4, sizeof( char * ), compare );
You are sorting the array of structs. sizeof(char *)is the wrong
element width. Make this:
qsort(devlist,4,sizeof *devlist,compare);
// bsearch is the next thing to work out how to do!
// void *bsearch( const void *key, const void *base, size_t num, size_t
width, int
// ( __cdecl *compare ) ( const void *elem1, const void *elem2 ) );
return 0;
}

int compare( const void* val1, const void* val2 )
{
struct mystruct *sp1 = (mystruct*)val1;
struct mystruct *sp1 = (struct mystruct *)val1;
or better:
const struct mystruct *sp1 = val1;
struct mystruct *sp2 = (mystruct*)val2;
same as above.
// IS THIS CORRECT?
return (int)(sp1->nKey - sp2->nKey);
This return statement has a potential problem in the operands in the
substraction may have values that could cause the long type to
overflow or underflow. It would be better to use something like:

return (sp2->nKey > sp1->nKey)?-1:(sp2->nKey != sp1->nKey);
}

--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #5
Angus Comber wrote:

Here is my code so far. Is this correct/incorrect/along the
right lines/other?
.... snip most code ...
int compare( const void* val1, const void* val2 )
{
struct mystruct *sp1 = (mystruct*)val1;
struct mystruct *sp2 = (mystruct*)val2;
// IS THIS CORRECT?
return (int)(sp1->nKey - sp2->nKey);
}


Almost. See revisions below:

int compare(const void* val1, const void* val2)
{
const struct mystruct *sp1 = val1;
const struct mystruct *sp2 = val2;
/* Preserve const, no useless error hiding casts */

/* // comments are not correct without a C99 compiler */

if (sp1->nKey > sp2->nKey) return 1;
else if (sp1->nKey < sp2->nKey) return -1;
else return 0;
/* subtraction may overflow, fouling everything */
} /* compare */

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!

Nov 14 '05 #6
I am, as they say in Peckham, a plonker - I should have noticed that!

Thank you.

Angus
"Leor Zolman" <le**@bdsoft.com> wrote in message
news:q2********************************@4ax.com...
On Thu, 5 Feb 2004 15:27:38 -0000, "Angus Comber"
<an***@iteloffice.com.PLEASENOSPAM> wrote:
Hello

Thanks for that. I am using VC++ so it didn't complain at the mystruct
line!

However, real reason for replying is that on first call of compare function,if I do this:

struct mystruct *sp1 = (mystruct*)val1;
struct mystruct *sp2 = (mystruct*)val2;
sp1->nKey is some wierd value - 775043377
sp2->nKey is 9

on the second call to compare the values are:
sp1->nKey is some wierd value - 775435825
sp2->nKey is 775043377

So I have definitely done something wrong!

Sorry, my bad. I just ran it, it worked, and I didn't look hard enough
at the ordering...it was actually not in descending order.

Here's the problem: in your qsort call:

qsort( (void *)devlist, (size_t)4, sizeof( char * ), compare);

the 3rd parameter should be
sizeof (mystruct)
instead of
sizeof (char *)

I failed to double-check against my own mental checklist for args to
qsort:
"base, nel, width, compare"
-leor

Any ideas?

"Leor Zolman" <le**@bdsoft.com> wrote in message
news:58********************************@4ax.com.. .
On Thu, 5 Feb 2004 14:43:22 -0000, "Angus Comber"
<an***@iteloffice.com.PLEASENOSPAM> wrote:
Please use a short subject line, and put the complete text of your
question in the message body.

>
>#include <stdio.h>
>#include <string.h>
>#include <search.h>
>struct mystruct
>{
> long nKey;
> char szIP[20];
>};

So is this C or C++? If C++, fine. If C, in order to use "mystruct" as
a typename (without having to say "struct mystruct", add this:

typedef struct mystruct mystruct;

>
>int compare( const void *long1, const void *long2 );
>
>int main()
>{
> mystruct devlist[4];

To do the above in C, add the aforementioned typedef.

> devlist[0].nKey = 9;
> strcpy(devlist[0].szIP, "192.168.1.1");
> devlist[1].nKey = 2;
> strcpy(devlist[1].szIP, "192.168.1.2");
> devlist[2].nKey = 7;
> strcpy(devlist[2].szIP, "192.168.1.3");
> devlist[3].nKey = 1;
> strcpy(devlist[3].szIP, "192.168.1.4");
> qsort( (void *)devlist, (size_t)4, sizeof( char * ), compare );
>
> // bsearch is the next thing to work out how to do!
> // void *bsearch( const void *key, const void *base, size_t num, size_t >width, int
> // ( __cdecl *compare ) ( const void *elem1, const void *elem2 ) );
> return 0;
>}
>
>int compare( const void* val1, const void* val2 )
>{
> struct mystruct *sp1 = (mystruct*)val1;
> struct mystruct *sp2 = (mystruct*)val2;
> // IS THIS CORRECT?
> return (int)(sp1->nKey - sp2->nKey);

If you want to sort in descending order, yes. If you want to sort in
_ascending_ order, flip the operands around.

Overall, a good first stab if you've never used qsort before.

Have fun,
-leor

>}

Leor Zolman
BD Software
le**@bdsoft.com
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html


Leor Zolman
BD Software
le**@bdsoft.com
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html

Nov 14 '05 #7
Leor Zolman wrote:
On Thu, 5 Feb 2004 14:43:22 -0000, "Angus Comber"
<an***@iteloffice.com.PLEASENOSPAM> wrote:
#include <stdio.h>
#include <string.h>
#include <search.h>
struct mystruct
{
long nKey;
char szIP[20];
};


So is this C or C++?


It's C. The newsgroup in which he posted it is a bit of a giveaway.
int compare( const void* val1, const void* val2 )
{
struct mystruct *sp1 = (mystruct*)val1;
struct mystruct *sp2 = (mystruct*)val2;
// IS THIS CORRECT?
return (int)(sp1->nKey - sp2->nKey);


If you want to sort in descending order, yes. If you want to sort in
_ascending_ order, flip the operands around.

Overall, a good first stab if you've never used qsort before.


You could have showed him a better way (I'll avoid your typedef, but not
because I don't think it's a good idea):

int compare(const void *val1, const void *val2)
{
const struct mystruct *sp1 = val1;
const struct mystruct *sp2 = val2;

return sp1->nKey < sk2->nKey ? -1: sp1->nKey > sp2->nKey;
}

This version avoids casting away constness, and doesn't invoke potential
overflow in the subtraction (and thus undefined behaviour).

--
Richard Heathfield : bi****@eton.powernet.co.uk
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
Nov 14 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Dimitris Mandalidis | last post by:
Hello all, Suppose we have the following struct : struct foo { int a; int b; char *c; } And :
5
by: Steve | last post by:
can someone tell me how qsort function in <stdlib.h> is used (qsort(..........))? the function has a buffer, two void * parameters and the a pointer to a compare function. Thanks.
17
by: Trent Buck | last post by:
The fourth argument is a comparator that returns `an integer less than, equal to, or greater than zero' depending on the ordering of its arguments. If I don't care about the order and simply...
32
by: John Smith | last post by:
I'm trying to figure out qsort(). I haven't seen any practical examples, only synopsis. In the code below, the array is not sorted. Can someone give me some help? #include <stdio.h> #include...
4
by: PCHOME | last post by:
Hi! I have questions about qsort( ). Is anyone be willing to help? I use the following struct: struct Struct_A{ double value; ... } *AA, **pAA;
5
by: Bidule | last post by:
Hi, I'm trying to sort structs defined as follows: struct combinationRec { float score; char* name; }; The number of structs and the length of the "name" field are not known
14
by: subramanian100in | last post by:
What is meant by stable qsort ?
4
by: davidcollins001 | last post by:
Hi, I am trying to get more to grips with pointers in C so I am trying to make a program that reads a file, places the data in a struct then sorts it using qsort. I have just about got my head...
61
by: Ron Ford | last post by:
K&R has three different versions of qsort, and the ultimate one is supposed to be like the one in the std library. I'm trying to implement the first, which is in §4.10. I think I'm pretty close...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.