qsort problem 
Author Message
 qsort problem



12:58:42 -0800):

:I am a beginner and I apologize for the fact that the following code is
:NOT "elegant" at all. I tried to create a record of 5 employees and
:sorted alphabetically by name. When I compiled it using MS Visual C++ on
:my PC, the following error message came up:

:C:\Ansic~1\four.cpp(72) : error C2664: 'qsort' : cannot convert
:parameter 4 from 'int (struct emprec,struct emprec)' to 'int (__cdecl
:*)(const void *,const void *)' (new behavior; please see help)
:Error executing cl.exe.
:four.exe - 1 error(s), 0 warning(s)

:I have no clue what it means and could somebody please provide a hint as
:to how I can fix it. Thank you in advance.

I have corrected that problem and made some additional notes in the following.
As usual, look for the `/* mha - ... */' comments.  

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAXEMP 5
#define SIZE 79

struct date {
    int month;
    int day;
    int year;

Quote:
};

struct emprec {
    char name[25];
    char room[10];
    short joblevel;
    long int salary;
    struct date startdate;

Quote:
};

 /* mha - was `int namesort(struct emprec employee1, struct emprec
  * employee2)'.  qsort requires that the comparison function be of the
  * form `int (*compar) (const void *, const void *)'. */
int namesort(const void *p1, const void *p2)
{
    const struct emprec *employee1 = p1, *employee2 = p2;   /* mha - added */
#if 0
    /* mha - the original function body (here) is replaced below the
     * `#endif' */
    if (strcmp(employee1.name, employee2.name) < 0)
        return (-1);
    else if (strcmp(employee1.name, employee2.name) == 0)
        return (0);
    else
        return (1);
#endif
    return strcmp(employee1->name, employee2->name);

Quote:
}

 /* mha - was `void main(void)'.  `main' returns an int */
int main(void)
{
    int i = 0;
    struct emprec employee[MAXEMP];
    FILE *fp;
    char buf[SIZE];

    if ((fp = fopen("c:/windows/emprec.ascii", "r")) == (FILE *) NULL) {
        /* mha - hard coding the path is usually a bad idea */
        fprintf(stderr, "Can't read file! \n");
        exit(EXIT_FAILURE);     /* mha - was `exit(1);' */
    }
    while (fgets(buf, sizeof buf, fp)) {
        /* mha - was `while (fgets(buf, SIZE + 1, fp)) {' */

        sscanf(buf, "%s %s %hd %ld %d %d %d",
               employee[i].name,/* mha - was `&employee[i].name,' */
               employee[i].room,/* mha - was `&employee[i].room,' */
               &employee[i].joblevel,
               &employee[i].salary,
               &(employee[i].startdate.month),
               &(employee[i].startdate.day),
               &(employee[i].startdate.year));
        /* mha - you should check to see if `sscanf' has indeed found
         * the 7 fields for which you were looking */

        printf("%s %s %hd %ld %d %d %d \n",
               employee[i].name,
               employee[i].room,
               employee[i].joblevel,
               employee[i].salary,
               (employee[i].startdate.month),
               (employee[i].startdate.day),
               (employee[i].startdate.year));

        i++;
    }

    /* mha - in the call to qsort and in the loop following, you do not
     * want to use MAXEMP, but a value which is the number of employees
     * successfully processed above */
    qsort(employee, MAXEMP, sizeof(struct emprec), namesort);

    printf("SORT BY NAME \n");
    for (i = 0; i < MAXEMP; i++)
        printf("%s %s %hd %ld %d %d %d \n",
               employee[i].name,
               employee[i].room,
               employee[i].joblevel,
               employee[i].salary,
               employee[i].startdate.month,
               employee[i].startdate.day,
               employee[i].startdate.year);
    /* mha - excess parens removed above.  They are OK, but unnecessary */
    return 0;                   /* mha - added */

Quote:
}


Honors Bridge Club, 115 E 57th, New York    

 * all newsgroups follow-ups are also emailed */


Fri, 16 Apr 1999 03:00:00 GMT  
 qsort problem

Quote:

> Hello,

> I am a beginner and I apologize for the fact that the following code is
> NOT "elegant" at all. I tried to create a record of 5 employees and
> sorted alphabetically by name. When I compiled it using MS Visual C++ on
> my PC, the following error message came up:

> C:\Ansic~1\four.cpp(72) : error C2664: 'qsort' : cannot convert
> parameter 4 from 'int (struct emprec,struct emprec)' to 'int (__cdecl
> *)(const void *,const void *)' (new behavior; please see help)
> Error executing cl.exe.
> four.exe - 1 error(s), 0 warning(s)

> I have no clue what it means and could somebody please provide a hint as
> to how I can fix it. Thank you in advance.

> Vinh

> #include <stdio.h>
> #include <string.h>
> #include <stdlib.h>

> #define MAXEMP 5
> #define SIZE 79

> struct date{
>       int     month;
>       int day;
>       int     year;
> };

> struct emprec{
>       char name[25];
>       char room[10];
>       short joblevel;
>       long int salary;
>       struct date startdate;
> };

> int namesort (struct emprec employee1, struct emprec employee2)
> {
>       if (strcmp(employee1.name, employee2.name)<0)
>               return (-1);
>       else if (strcmp(employee1.name, employee2.name)==0)
>               return (0);
>       else
>               return (1);
> }

Rewrite this as follows:

int namesort(const void *left, const void *right)
{
   const struct emprec *employee1 = left;
   const struct emprec *employee2 = right;

   if (strcmp(employee1->name, employee2->name) < 0)
       return -1;
   else if (strcmp(employee1.name, employee2.name)==0)
       return 0;
   else
       return 1;

Quote:
}

or, simpler:

int namesort(const void *left, const void *right)
{
   return strcmp(((struct emprec *) left)->name,
                 ((struct emprec *) right)->name);

Quote:
}

Braces around return arguments are not necessary.

Quote:

> void main(void)

In C, main returns an int.  Make it `int main(void)' and add a return
statement at the end of main (return EXIT_SUCCESS or EXIT_FAILURE).

Quote:
> {
>       int i=0;
>       struct emprec employee[MAXEMP];
>       FILE *fp;
>       char buf[SIZE];

>       if((fp = fopen("c:/windows/emprec.ascii","r")) == (FILE*) NULL)

The cast of NULL to FILE * is unnecessary.

Quote:
>       {
>               fprintf(stderr, "Can't read file! \n");
>                       exit(1);
>       }

>       while (fgets(buf,SIZE+1,fp))

Not SIZE+1 but SIZE, or sizeof(buf).  And you should make sure that no
more than MAXEMP records are being read from the file.

Quote:
>       {

>                       sscanf (buf, "%s %s %hd %ld %d %d %d",

Better say
    sscanf (buf, "%24s %9s %hd %ld %d %d %d",

Quote:
>                       &employee[i].name,
>                       &employee[i].room,
>                       &employee[i].joblevel,
>                       &employee[i].salary,
>                       &(employee[i].startdate.month),
>                       &(employee[i].startdate.day),
>                       &(employee[i].startdate.year));

Address operator not necessary for `name' and `room'.

Quote:

>               printf( "%s %s %hd %ld %d %d %d \n",
>                       employee[i].name,
>                       employee[i].room,
>                       employee[i].joblevel,
>                       employee[i].salary,
>                       (employee[i].startdate.month),
>                       (employee[i].startdate.day),
>                       (employee[i].startdate.year));

>               i++;
>       }

>       qsort(employee, MAXEMP, sizeof(struct emprec),namesort);

You should add a variable, say `empcount', which counts how many
employee records have been read from the file (say `empcount = i;' just
after the scanf loop, or use empcount as index in the loop, instead of `i').

Replace MAXEMP in the qsort call and the print loop below by
`empcount'.  Otherwise, you will sort and print uninitialized records,
which may easily crash your program.

Quote:

>       printf("SORT BY NAME \n");
>       for (i=0; i<MAXEMP;i++)
>               printf( "%s %s %hd %ld %d %d %d \n",
>                       employee[i].name,
>                       employee[i].room,
>                       employee[i].joblevel,
>                       employee[i].salary,
>                       (employee[i].startdate.month),
>                       (employee[i].startdate.day),
>                       (employee[i].startdate.year));

Add `return EXIT_SUCCESS' here.

Quote:
> }

--

IBM European Networking Center . . . VNET: GEHLERT at MAZVM01
Telecooperation Department . . . .  Phone: +49-6221-59-4429 (FAX -3300)
Vangerowstr. 18 . . . . . . . . . . . ITN: *142-4429
D-69118 Heidelberg

- Show quoted text -

Quote:
>>> Opinions are my own, not those of IBM. <<<



Fri, 16 Apr 1999 03:00:00 GMT  
 qsort problem

Quote:

[snip]
> C:\Ansic~1\four.cpp(72) : error C2664: 'qsort' : cannot convert
> parameter 4 from 'int (struct emprec,struct emprec)' to 'int (__cdecl
> *)(const void *,const void *)' (new behavior; please see help)
> Error executing cl.exe.
> four.exe - 1 error(s), 0 warning(s)

[snip]

> int namesort (struct emprec employee1, struct emprec employee2)
> {
[snip]
>         qsort(employee, MAXEMP, sizeof(struct emprec),namesort);

[snip]

V.Q.,

'qsort' is expecting 'const void *' as arguments, therefore:

Change your prototype for 'namesort':

  int namesort ( const void *aemp, const void *bemp );

Change your function:

int namesort ( const void *aemp, const void *bemp )
{
  struct emprec *employee1 = (struct emprec *)aemp;
  struct emprec *employee2 = (struct emprec *)bemp;

  return( strcmp(employee1->name,employee2->name) );

Quote:
}

Yours,

Geoff Houck
systems hk

http://www.teleport.com/~hksys



Fri, 16 Apr 1999 03:00:00 GMT  
 qsort problem

Quote:

> int namesort ( const void *aemp, const void *bemp )
> {
>   struct emprec *employee1 = (struct emprec *)aemp;
>   struct emprec *employee2 = (struct emprec *)bemp;

Correct, but this is `casting away a const' which in my mind is very
bad style. In fact, with my usual options to my compiler, the compiler
will warn on this.

Why not

const struct emprec *employee1 = aemp;
const struct emprec *employee2 = bemp;

instead?

Cheers
Tanmoy
--

Tanmoy Bhattacharya O:T-8(MS B285)LANL,NM87545 H:#9,3000,Trinity Drive,NM87544
Others see <gopher://yaleinfo.yale.edu:7700/00/Internet-People/internet-mail>,
<http://alpha.acast.nova.edu/cgi-bin/inmgq.pl>or<ftp://csd4.csd.uwm.edu/pub/
internetwork-mail-guide>. -- <http://nqcd.lanl.gov/people/tanmoy/tanmoy.html>
fax: 1 (505) 665 3003   voice: 1 (505) 665 4733    [ Home: 1 (505) 662 5596 ]



Sat, 17 Apr 1999 03:00:00 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. qsort problem

2. qsort problem

3. qsort problem

4. Qsort problem, not sorting?

5. qsort problem

6. qsort problem solved !!!

7. qsort() problems with casting compare() call...

8. A qsort problem...

9. QSort problems

10. qsort problem

11. qsort problem

12. qsort problem -- pointer type

 

 
Powered by phpBB® Forum Software