Thread: qsort(): fcmp function

  1. #1
    Registered User Sargnagel's Avatar
    Join Date
    Aug 2002
    Posts
    166

    Question qsort(): fcmp function

    Code:
    typedef struct list
    {
        unsigned short int result;
        unsigned short int count;
        double score;
        char name[22];
    }prts;
    
    prts datadump[20000];
    
    int sort_results( const void *a, const void *b ) 
    {
        const prts *pa = a;
        const prts *pb = b;
        
        if ( pa->result > pb->result ) return -1;
        if ( pa->result < pb->result ) return 1;
        return 0;
    }
    This is the fcmp function I am currently passing to qsort() to sort an array of structures.
    My question is: How can I avoid writing a function for every variable of the structure by which I want to sort the array of structures?

    Thank you very much for your help.
    Last edited by Sargnagel; 10-24-2002 at 01:43 PM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Which do you mean

    - sort by result, and if result is equal sort by count
    - sort by result then sometime later sort by count
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Green Member Cshot's Avatar
    Join Date
    Jun 2002
    Posts
    892
    There's really no way of getting around the comparisons. But you can avoid writing a different function for every variable by creating a new structure:

    Code:
    typedef struct list
    {
        unsigned short int result;
        unsigned short int count;
        double score;
        char name[22];
    }prts;
    
    typedef struct bleh
    {
        int varID; /* specific parameter you want to compare */
        prts blah;
    }BLEH;
    Then you can set the varID before you pass your new structures into the qsort. Then switch on the right variable in your compare function. This is just one way of doing it though.

    Dunno if you mean to do this or not, but you're sorting on descending order.
    Try not.
    Do or do not.
    There is no try.

    - Master Yoda

  4. #4
    Registered User Sargnagel's Avatar
    Join Date
    Aug 2002
    Posts
    166
    sort by result then sometime later sort by count
    Exactly! Sorry for not making this clear from the start.
    qsort(result) --> fprintf --> qsort(count) --> fprintf ...

    Dunno if you mean to do this or not, but you're sorting on descending order.
    That's what I want. The high values are the interesting ones in this case.
    Thank you for your help, Cshot. I will try your solution if Salem doesn't come up with some magic code.

    One additional question:
    Why is the function working with "const prts *pa = a;" instead of "const datadump *pa = a;"?
    Last edited by Sargnagel; 10-24-2002 at 02:55 PM.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    I don't think this really counts as magic

    Code:
    enum { SORT_BY_RESULT, SORT_BY_COUNT };
    int sort_by;
    int sort_results( const void *a, const void *b ) {
        const prts *pa = a;
        const prts *pb = b;
        int result = 0;
        switch ( sort_by ) {
            case SORT_BY_RESULT:
                if ( pa->result > pb->result ) result = -1;
                if ( pa->result < pb->result ) result = 1;
            break;
            case SORT_BY_COUNT:
                if ( pa->count > pb->count ) result = -1;
                if ( pa->count < pb->count ) result = 1;
            break;
        }
        return result;
    }
    
    Then you would do
    sort_by = SORT_BY_RESULT; qsort() ; fprintf();
    sort_by = SORT_BY_COUNT; qsort() ; fprintf();
    To be honest, if you've only got a few functions to write, then copy/paste is probably just as good - and it saves messing around with globals.

    But if your structure had like 10's of members, then we could get creative in different ways

    > Why is the function working with "const prts *pa = a;" instead of "const datadump *pa = a;"?
    prts is the type name, datadump is a variable name
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User Sargnagel's Avatar
    Join Date
    Aug 2002
    Posts
    166
    I don't think this really counts as magic
    At my current skill level this IS magic!

    Code:
    int result = 0;
    ...
    return result;
    Why? I thought I am accessing the variable result in the array of structures? And why 'return'? I am a little bit confused.

    But if your structure had like 10's of members, then we could get creative in different ways

    Well, the structure is still in development and the number of variables by which to sort might well exceed 10 ... maybe it will be about 15 to 20. If you've something creative in mind then please let me know!

    prts is the type name, datadump is a variable name
    Okay! Thnx. I've thought about it again - now it's clear.

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > Why? I thought I am accessing the variable result in the array of structures?
    You are - it's just a bad choice of variable name

    result and pa->result are two different things

    > int result = 0;
    qsort cmp() functions return -1, 0, +1
    I'm just guessing at the answer so there are only two left to worry about in the code.

    Then I set result to either +1 or -1 depending on the comparison

    > And why 'return'? I am a little bit confused.
    Huh?
    You had returns in your code - this just returns the contents of a local var rather than a compile-time constant.

    > If you've something creative in mind then please let me know!
    When you are ready, I will
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Registered User Sargnagel's Avatar
    Join Date
    Aug 2002
    Posts
    166
    result and pa->result are two different things

    Now I got it! At first glance it was a little bit disturbing.
    Thanks for making this clear.

    > If you've something creative in mind then please let me know!

    When you are ready, I will


    Okay! I will continue to develop my program and come back to you when I've the final structure ... although it will not remain unchanged in the future. The structure will be updated as I add new calculations and thus new variables by which to sort.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 05-13-2011, 08:28 AM
  2. In over my head
    By Shelnutt2 in forum C Programming
    Replies: 1
    Last Post: 07-08-2008, 06:54 PM
  3. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  4. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  5. Replies: 5
    Last Post: 02-08-2003, 07:42 PM