Optional parameters: Difference between revisions

Content added Content deleted
(Added Oz example.)
(Added C)
Line 76: Line 76:
</pre>
</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++}}==
=={{header|C++}}==
This implementation only accepts function pointers for the comparators, and does not accept function objects, for simplicity.
This implementation only accepts function pointers for the comparators, and does not accept function objects, for simplicity.