Sorted List Presentation, Part I

Sometimes programming can be a snap, especially when you have a known data set and pretty much all the values are static. You can whip out code right away, it runs well and looks beautiful — but that’s because everything is known. The fewer variables, the easier to code.

As an example, consider a list of items:

    char *fruit[] = {
        "apple", "orange", "blueberry", "date", "melon",
        "grape", "peach", "mango", "watermelon", "pear",
        "olive", "plum", "nectarine", "kiwi", "loquat",
        "honeydew", "lime", "grapefruit", "cherry",
        "avocado", "tomato", "banana", "cantaloupe",
        "huckleberry", "kumquat", "tangerine", "fig",
        "raspberry", "papaya", "lychee", "guava"
    };

The fruit[] array consists of strings (char pointers). If you were to sort this array and present the list, the following code does the job:

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

#define ITEMS 30

int compare(const void *a, const void *b);

int main()
{
    char *fruit[] = {
        "apple", "orange", "blueberry", "date", "melon",
        "grape", "peach", "mango", "watermelon", "pear",
        "olive", "plum", "nectarine", "kiwi", "loquat",
        "honeydew", "lime", "grapefruit", "cherry",
        "avocado", "tomato", "banana", "cantaloupe",
        "huckleberry", "kumquat", "tangerine", "fig",
        "raspberry", "papaya", "lychee"
    };
    int x;

/* quicksort the list */
    qsort(fruit,ITEMS,sizeof(char *),compare);

/* display sorted strings */
    for(x=0;x<ITEMS;x++)
    {
        printf("%s\n",fruit[x]);
    }

    return(0);
}

/* compare routine for quicksort */
int compare(const void *a, const void *b)
{
    const char **pa, **pb;

    pa = (const char **)a;
    pb = (const char **)b;
    return( strcmp(*pa,*pb) );
}

The meat of this code is the quicksort function, qsort() at Line 23. You can read the details here, and see that the bulk of the code was copied from that earlier Lesson.

The output shows the sorted list of 30 items. The code relies upon the ITEMS constant, which reflects the number of elements in the array. So the programmer (me) assumes that the number of elements won’t change, which is okay — so far.

Now assume that The Boss likes the code, but the single-column list is too long. So he directs you to present the list in rows and columns. That modification is simple enough: Only the output part of the code changes:

/* display sorted strings */
    x = 0;
    while(x < ITEMS)
    {
        printf("%-12s",fruit[x]);
        x++;
        /* new row each 5 items */
        if( x%5 == 0)
            putchar('\n');
    }

I elected to use a while loop because it’s easier to process the elements one at a time, using a single variable x as a counter, than to mess with an extra variable required for nested for loops.

In the printf() statement, the %-12s placeholder left-aligns each string within 12 spaces, which helps line-up the output. (Relevant Lesson here.) And 12 is chosen because the longest string in the array, huckleberry, is 11 characters long; it’s a known value.

The if( x%5 == 0 ) statement pops out a newline after every five elements. The output presents the sorted list in six rows of five columns:

apple       avocado     banana      blueberry   cantaloupe   
cherry      date        fig         grape       grapefruit  
honeydew    huckleberry kiwi        kumquat     lime        
loquat      lychee      mango       melon       nectarine   
olive       orange      papaya      peach       pear        
plum        raspberry   tangerine   tomato      watermelon

It looks good to me, but I’m only the programmer. The Boss, on the other hand, is puzzled that the list isn’t sorted by columns. In other words, he wants this output instead:

apple       date        kiwi        melon       pear        
avocado     fig         kumquat     nectarine   plum        
banana      grape       lime        olive       raspberry   
blueberry   grapefruit  loquat      orange      tangerine   
cantaloupe  honeydew    lychee      papaya      tomato      
cherry      huckleberry mango       peach       watermelon

In the first column is apple through cherry, then date through mango in the second column, and so on. The code for this output is presented in next week’s Lesson. Even so, this Lesson began as an Exercise, one that proved more difficult than I had planned. So if you want to concoct your own code for the above output, please do so.

Leave a Reply