Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7873717
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 3, 20262026-06-03T02:35:42+00:00 2026-06-03T02:35:42+00:00

I made a qsort function for a larger program. It is to sort by

  • 0

I made a qsort function for a larger program. It is to sort by time. I have a class schedule I am working with and found a need to compare time with AM and PM. ie if A is chosen then all the classes in the morning, if P is chosen all the classes in the afternoon. My question is this, is there a way to use this sort function with a greater than or less than comparator? If so can someone show me how if it is not to much trouble?

int sortFunction(const void *p, const void *q) {
    return ((sched_record *) p)->start.hour -
                   ((sched_record *) q)->start.hour;
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-03T02:35:44+00:00Added an answer on June 3, 2026 at 2:35 am

    Writing a comparator

    In C, the comparator function from qsort() returns a number less than, equal to, or greater than zero according to whether the data structure represented by the first argument should be sorted before, equal to, or after the second parameter.

    Sorting am and pm times is painful; even converting from am/pm to 24-hour is not entirely trivial. It is far better to store time values in 24 hour notations (or even as seconds since The Epoch). The presentation layer should deal with presenting the time in am/pm notation; the model and controller layers should usually avoid messing with am/pm. Don’t forget:

    12:01 am happens 1 hour   before  1:01 am
    11:59 am happens 1 minute before 12:00 pm
    12:00 pm happens 1 hour   before  1:00 pm
    

    Assuming you are not constrained to events starting on the hour and that you have resolved to use 24 hour times internally, then you can write code such as:

    int SchedRecordTimeComparator(void const *v1, void const *v2)
    {
        sched_record const *r1 = v1;  /* I don't mind a cast; there are those who do */
        sched_record const *r2 = v2;
        if (r1->start.hour < r2->start.hour)
            return -1;
        else if (r1->start.hour > r2->start.hour)
            return +1;
        else if (r1->start.minute < r2->start.minute)
            return -1;
        else if (r1->start.minute > r2->start.minute)
            return +1;
        else
            return  0;
    }
    

    It is fairly obvious how to extend that to manage seconds or other match criteria. Note that this code does not run the risk of integer overflow, whereas subtracting two numbers could in general run into overflow problems.

    If you decide to continue with 12 hour clocks, then you will have to have a way to distinguish 6 am from 6 pm. Basically, you’ll convert your 12 hour notation into 24 hour notation in the function, then do the comparison on that basis (I’m assuming AM and PM are enumeration constants):

    int SchedRecordTimeComparator(void const *v1, void const *v2)
    {
        sched_record const *r1 = v1;  /* I don't mind a cast; there are those who do */
        sched_record const *r2 = v2;
        int hhmm1 = ((r1->start.hour % 12) + (r1->start.am_pm == AM ? 0 : 12)) * 60 +
                      r1->start.minute;
        int hhmm2 = ((r2->start.hour % 12) + (r2->start.am_pm == PM ? 0 : 12)) * 60 +
                      r2->start.minute;
        if (hhmm1 < hhmm2)
            return -1;
        else if (hhmm1 > hhmm2)
            return +1;
        else
            return  0;
    }
    

    How might this be used?

    I am not really sure on how to use it?

    Usage is fairly simple. Somewhere in your program, you have an array of sched_records:

    sched_record *array = malloc(num_records * sizeof(*array));
    ...
    ...fill up array with data...
    ...
    qsort(array, num_records, sizeof(*array), SchedRecordTimeComparator);
    ...
    

    That’s all there is to it. It could be a fixed size array instead:

    sched_record array[NUM_RECORDS];
    

    Then, assuming you still have a variable size_t num_records which indicates how many of the records are in use, you use the same qsort() call. Using qsort() is very straight-forward. Using bsearch() is slightly more complex, because you typically have to fake up a record to find:

    sched_record *SchedRecordSearch(int hour, int minute, sched_record *array, size_t num_records)
    {
        sched_record key = { .start.hour = hour, .start.minute = minute };
        return bsearch(&key, array, num_records, sizeof(*array), SchedRecordTimeComparator);
    }
    

    Using C99 and designated initializers makes it easier. You have to ensure that your key record has an appropriate value in each of the fields that will be used by the comparator. Of course, you’ve already sorted the array with qsort() before you use bsearch() on it — or made sure that the data is in the same sorted order ‘as if’ you had done a qsort() on it with the same comparator.

    It’s also worth writing a function to check the sort order of an array — it is straight-forward, and left as an ‘exercise for the reader’. You can then use that in assertions, for example.


    Don’t write your own qsort()

    I note that all of us answering the question are assuming that you are using the Standard C Library sort function, yet your question suggests you’ve written your own. Generally speaking, you’ll have to be very good to do better than the system-provided qsort(); I wouldn’t bother to write my own unless I could demonstrate that the system function was too slow.

    • Use the system-provided qsort() until you don’t need to ask how to write one for yourself.

    If you must still write the code, then you need to decide on the interface. You can either mimic the standard interface (but use a different name), or you can write a custom interface tied to one specific type (which must be re-parameterized if you need to sort a different type). The latter is roughly what C++ does with templates.

    One of the problems for writing your own generic comparator is swapping the elements when you don’t know how big the elements will be in advance. If you can use C99 and VLAs, it isn’t too bad, though if the size of an element blows your stack, then you’re completely hosed.

    Inside the function, you have to be careful to use char * instead of void * because you can’t legitimately do pointer arithmetic on void *, notwithstanding that GCC does allow you to do so as a non-standard extension.

    You need to make sure you have a clear picture of how the data is laid out, and what your sorting code will be doing to it. You’ll take a comparator like the ones described in the various answers, and when you need to do a comparison, you’ll do something like:

     int cmp = (*Comparator)(char_base + (i * element_size), char_base + (j * element_size));
    

    You can then do:

     if (cmp < 0)
         act on "element i smaller than element j"
     else if (cmp > 0)
         act on "element i greater than element j"
     else
         act on "elements i and j are equal"
    

    Showing Different Ranges

    I’m not sure it would do what I want. I have to look more closely. My sort function I originally posted did sort by time from earliest to latest. I may not have been clear on my question. In the menu portion of my program, I have an option line of sorting by AM, PM or Don’t care. A is for classes starting before 12:00 PM, P is for classes starting at noon or later, and D for don’t care. If the user chooses A, than list the classes up to 12:00, etc. If yours does that, than how do I make that distinction?

    You’re confusing two things: sorting the data and presenting the right subset of the data. You sort the data as discussed/shown. This gives you a sorted array. Then you scan through the array to present the entries in the time range you are interested in. That will be a separate function; you might well still use the comparator function, but you’d create a pair of dummy keys for the start and end of the time range (each key would be a bit like the key in the bsearch() example in my answer) and then look for all the records in the sorted array after the start time and before the end time.

    I’m about to make some simplifying assumptions. Your start.hour records the time unambiguously as a number of minutes since midnight, and it is an integer.

    1. Sort the array:

      qsort(array, num_records, sizeof(*array), SchedRecordTimeComparator);
      
    2. Generate the correct keys — lo and hi:

      typedef struct sched_range
      {
          sched_record *lo;
          sched_record *hi;
      } sched_range;
      
      sched_record lo, hi;
      if (choice == 'A')
      {
          lo.start.hour = 0;        /* Midnight (am) */
          hi.start.hour = 12 * 60;  /* Midday */
      }
      else if (choice == 'D')
      {
          lo.start.hour = 12 * 60;  /* Midday */
          hi.start.hour = 24 * 60;  /* Midnight (pm) */
      }
      else
      {
          lo.start.hour = 0;        /* Midnight (am) */
          hi.start.hour = 24 * 60;  /* Midnight (pm) */
      }
      
    3. Write the SchedRangeSearch() function:

      sched_range SchedRangeSearch(sched_record const *array, size_t num_records,
                      sched_record *lo, sched_record *hi,
                      int (*comparator)(void const *v1, void const *v2))
      {
           sched_range r = { 0, 0 };
           sched_record const *ptr = array;
           sched_record const *end = array + num_records;
      
           /* Skip records before start time */
           while (ptr < end && (*comparator)(lo, ptr) < 0)
               ptr++;
           if (ptr >= end)
               return r;  /* No matching records */
      
           r.lo = ptr;  /* First record in range */
      
           /* Find first record after finish time - if any */
           while (ptr < end && (*comparator)(ptr, hi) < 0)
               ptr++;
      
           r.hi = ptr;
           return r;
      }
      
    4. Use the search function to find the range required:

      sched_range r = SchedRangeSearch(array, num_records, &lo, &hi, SchedRecordTimeComparator);
      
    5. Show the relevant records:

      if (r.lo != 0)
      {
          assert(r.hi != 0);
          sched_record *ptr;
      
          for (ptr = r.lo; ptr < r.hi; ptr++)
              show_sched_record(ptr);
      }
      else
          show_empty_schedule();
      

    Untested code: beware crashes, out of bounds access, etc.

    The intention is that the search function provides two pointers, to the start (first valid item in the range) and end of the range, where the end pointer points beyond the last valid item. Hence the for loop to display the valid data goes from start to strictly less than end. (This is the same convention used in C++ with STL iterators. It pays to reuse good ideas.)

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

This is how I made my comparison function to pass to qsort(): int charCompare(const
I made a function which displays date on the webpage,, and i uploaded the
I made small program to divide large pictures and take part of them. When
made a short java program in Bluej upon compiling it and trying to get
I made a view to abstract columns of different tables and pre-filter and pre-sort
I made a class from Linq to SQL Clasees with VS 2008 SP1 Framework
I made a discovery some time back. Just follow these steps: Create a .doc/.xls/.ppt
I made a class that derives from Component: public class MyComponent: System.ComponentModel.Component { }
I made a program. I also made my own file type, which the program
Made this custom alert box: <script type="text/javascript"> $(function () { var $alert = $('#alert');

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.