--- /dev/null
+#include <stdlib.h>
+#include <stdio.h>
+#include <wchar.h>
+#include <wctype.h>
+#include <locale.h>
+
+wchar_t *exclude[] = {
+ L"a",
+ L"an",
+ L"the",
+ L"in",
+ L"to",
+ L"from",
+ L"of",
+ L"and",
+ L"or",
+ NULL
+};
+
+wchar_t *seps = L"-.?!";
+wchar_t *nonseps = L"\'";
+
+void capitalize(wchar_t *str)
+{
+ wchar_t *p, *p2, **ce;
+ int f;
+
+ p = str;
+ f = 1;
+ while(1) {
+ while(!iswalnum(*p)) {
+ if(*p == L'\0')
+ return;
+ if(wcschr(seps, *p) != NULL)
+ f = 1;
+ p++;
+ }
+ p2 = p;
+ while(iswalnum(*p) || (wcschr(nonseps, *p) != NULL)) {
+ *p = towlower(*p);
+ p++;
+ }
+ if(f) {
+ *p2 = towupper(*p2);
+ f = 0;
+ } else {
+ for(ce = exclude; *ce != NULL; ce++) {
+ if(!wcsncmp(*ce, p2, p - p2) && ((*ce)[p - p2] == L'\0'))
+ break;
+ }
+ if(*ce == NULL)
+ *p2 = towupper(*p2);
+ }
+ }
+}
+
+int main(int argc, char **argv)
+{
+ int i;
+ wchar_t buf[256];
+
+ setlocale(LC_ALL, "");
+ if(argc > 1) {
+ for(i = 1; i < argc; i++) {
+ mbstowcs(buf, argv[i], sizeof(buf) / sizeof(*buf));
+ capitalize(buf);
+ fputws(buf, stdout);
+ fputwc(L'\n', stdout);
+ }
+ } else {
+ while(1) {
+ if(fgetws(buf, sizeof(buf) / sizeof(*buf), stdin) == NULL) {
+ if(feof(stdin))
+ break;
+ perror("reading input");
+ return(1);
+ }
+ capitalize(buf);
+ fputws(buf, stdout);
+ }
+ }
+ return(0);
+}
+
+/*
+ * Local Variables:
+ * compile-command: "gcc -Wall -g -o capitalize capitalize.c"
+ * End:
+ */