Task: Optional parameters

C: #include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>

typedef const char * String;
typedef struct sTable {
    String * *rows;
    int      n_rows,n_cols;
} *Table;

typedef int (*CompareFctn)(String a, String b);

struct {
   CompareFctn  compare;
   int   column;
   int   reversed;
} sortSpec;

int CmprRows( const void *aa, const void *bb)
{
   String *rA = *(String *const *)aa;
   String *rB = *(String *const *)bb;
   int sortCol = sortSpec.column;

   String left = sortSpec.reversed ? rB[sortCol] : rA[sortCol];
   String right = sortSpec.reversed ? rA[sortCol] : rB[sortCol];
   return sortSpec.compare( left, right );
}


int sortTable(Table tbl, const char* argSpec,... )
{
   va_list vl;
   const char *p;
   int c;
   sortSpec.compare = &strcmp;
   sortSpec.column = 0;
   sortSpec.reversed = 0;

   va_start(vl, argSpec);
   if (argSpec)
      for (p=argSpec; *p; p++) {
         switch (*p) {
         case 'o':
            sortSpec.compare = va_arg(vl,CompareFctn);
            break;
         case 'c':
            c = va_arg(vl,int);
            if ( 0<=c && c<tbl->n_cols)
               sortSpec.column  = c;
            break;
         case 'r':
            sortSpec.reversed = (0!=va_arg(vl,int));
            break;
         }
      }
   va_end(vl);
   qsort( tbl->rows, tbl->n_rows, sizeof(String *), CmprRows);
   return 0;
}

void printTable( Table tbl, FILE *fout, const char *colFmts[])
{
   int row, col;

   for (row=0; row<tbl->n_rows; row++) {
      fprintf(fout, "   ");
      for(col=0; col<tbl->n_cols; col++) {
         fprintf(fout, colFmts[col], tbl->rows[row][col]);
      }
      fprintf(fout, "\n");
   }
   fprintf(fout, "\n");
}

int ord(char v)
{
    return v-'0';
}


int cmprStrgs(String s1, String s2)
{
    const char *p1 = s1; 
    const char *p2 = s2;
    const char *mrk1, *mrk2;
    while ((tolower(*p1) == tolower(*p2)) && *p1) {
       p1++; p2++;
    }
    if (isdigit(*p1) && isdigit(*p2)) {
        long v1, v2;
        if ((*p1 == '0') ||(*p2 == '0')) {
            while (p1 > s1) {
                p1--; p2--;
                if (*p1 != '0') break;
            }
            if (!isdigit(*p1)) {
                p1++; p2++;
            }
        }
        mrk1 = p1; mrk2 = p2;
        v1 = 0;
        while(isdigit(*p1)) {
            v1 = 10*v1+ord(*p1);
            p1++;
        }
        v2 = 0;
        while(isdigit(*p2)) {
            v2 = 10*v2+ord(*p2);
            p2++;
        }
        if (v1 == v2) 
           return(p2-mrk2)-(p1-mrk1);
        return v1 - v2;
    }
    if (tolower(*p1) != tolower(*p2))
       return (tolower(*p1) - tolower(*p2));
    for(p1=s1, p2=s2; (*p1 == *p2) && *p1; p1++, p2++);
    return (*p1 -*p2);
}

int main()
{
   const char *colFmts[] = {" %-5.5s"," %-5.5s"," %-9.9s"};
   String r1[] = { "a101", "red",  "Java" };
   String r2[] = { "ab40", "gren", "Smalltalk" };
   String r3[] = { "ab9",  "blue", "Fortran" };
   String r4[] = { "ab09", "ylow", "Python" };
   String r5[] = { "ab1a", "blak", "Factor" };
   String r6[] = { "ab1b", "brwn", "C Sharp" };
   String r7[] = { "Ab1b", "pink", "Ruby" };
   String r8[] = { "ab1",  "orng", "Scheme" };

   String *rows[] = { r1, r2, r3, r4, r5, r6, r7, r8 };
   struct sTable table;
   table.rows = rows;
   table.n_rows = 8;
   table.n_cols = 3;

   sortTable(&table, "");
   printf("sort on col 0, ascending\n");
   printTable(&table, stdout, colFmts);

   sortTable(&table, "ro", 1, &cmprStrgs);
   printf("sort on col 0, reverse.special\n");
   printTable(&table, stdout, colFmts);

   sortTable(&table, "c", 1);
   printf("sort on col 1, ascending\n");
   printTable(&table, stdout, colFmts);

   sortTable(&table, "cr", 2, 1);
   printf("sort on col 2, reverse\n");
   printTable(&table, stdout, colFmts);
   return 0;
}


C++: #include <vector>
#include <algorithm>
#include <string>


template <class T>
struct sort_table_functor {
  typedef bool (*CompFun)(const T &, const T &);
  const CompFun ordering;
  const int column;
  const bool reverse;
  sort_table_functor(CompFun o, int c, bool r) :
    ordering(o), column(c), reverse(r) { }
  bool operator()(const std::vector<T> &x, const std::vector<T> &y) const {
    const T &a = x[column],
            &b = y[column];
    return reverse ? ordering(b, a)
                   : ordering(a, b);
  }
};


template <class T>
bool myLess(const T &x, const T &y) { return x < y; }


template <class T>
void sort_table(std::vector<std::vector<T> > &table,
                int column = 0, bool reverse = false,
                bool (*ordering)(const T &, const T &) = myLess) {
  std::sort(table.begin(), table.end(),
            sort_table_functor<T>(ordering, column, reverse));
}

#include <iostream>


template <class T>
void print_matrix(std::vector<std::vector<T> > &data) {
  for () {
    for (int j = 0; j < 3; j++)
      std::cout << data[i][j] << "\t";
    std::cout << std::endl;
  }
}


bool desc_len_comparator(const std::string &x, const std::string &y) {
  return x.length() > y.length();
}

int main() {

  std::string data_array[3][3] =
    {
      {"a", "b", "c"},
      {"", "q", "z"},
      {"zap", "zip", "Zot"}
    };

  std::vector<std::vector<std::string> > data_orig;
  for (int i = 0; i < 3; i++) {
    std::vector<std::string> row;
    for (int j = 0; j < 3; j++)
      row.push_back(data_array[i][j]);
    data_orig.push_back(row);
  }
  print_matrix(data_orig);

  std::vector<std::vector<std::string> > data = data_orig;
  sort_table(data);
  print_matrix(data);

  data = data_orig;
  sort_table(data, 2);
  print_matrix(data);

  data = data_orig;
  sort_table(data, 1);
  print_matrix(data);

  data = data_orig;
  sort_table(data, 1, true);
  print_matrix(data);

  data = data_orig;
  sort_table(data, 0, false, desc_len_comparator);
  print_matrix(data);

  return 0;
}