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. |