Optional parameters: Difference between revisions

Added C
(Added Oz example.)
(Added C)
Line 76:
</pre>
 
=={{header|C}}==
<lang c>#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
 
typedef char * String;
typedef struct sTable {
String * *rows;
int n_rows,n_cols;
} *Table;
 
typedef int (*CompareFctn)( const String a, const String b);
 
struct {
CompareFctn compare;
int column;
int reversed;
} sortSpec;
 
int CmprRows( const void *aa, const void *bb)
{
String **rA = (String **)aa;
String **rB = (String **)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 );
}
 
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* tbl parameter is a table of rows of strings
* argSpec is a string containing zero or more of the letters o,c,r
* if o is present - the corresponding optional argument is a function which
* determines the ordering of the strings.
* if c is present - the corresponding optional argument is an integer that
* specifies the column to sort on.
* if r is present - the corresponding optional argument is either
* true(nonzero) or false(zero) and if true, the sort will b in reverse order
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int sortTable(Table tbl, char* argSpec,... )
{
va_list vl;
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, 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)
{
char *digits="0123456789";
return strchr(digits, v)-digits;
}
 
/* an alternative comparison function */
int cmprStrgs(const String s1,const String s2)
{
char *p1 = s1;
char *p2 = s2;
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(int argc, char **argv)
{
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[] = { "Ab1a", "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, "");
fprintf(stdout, "sort on col 0, ascending\n");
printTable(&table, stdout, colFmts);
 
sortTable(&table, "ro", 1, cmprStrgs);
fprintf(stdout, "sort on col 0, reverse.special\n");
printTable(&table, stdout, colFmts);
 
sortTable(&table, "c", 1);
fprintf(stdout, "sort on col 1, ascending\n");
printTable(&table, stdout, colFmts);
 
sortTable(&table, "cr", 2, 1);
fprintf(stdout, "sort on col 2, reverse\n");
printTable(&table, stdout, colFmts);
return 0;
}</lang>
=={{header|C++}}==
This implementation only accepts function pointers for the comparators, and does not accept function objects, for simplicity.
Anonymous user