The solution for this month’s Exercise is perhaps a bit trickier than you may have anticipated. The issue is to set the first letter of a word as upper case and the remaining letters lowercase. The solution I devised involves reading two characters at a time.
I’m sure other solutions are possible, but for mine I created two variables: ch
and prev
. Both are integers, as to write a proper filter you must test for the EOF
(End Of File) condition. Variable ch
holds the current character and prev
holds the previously-read character.
By holding two variables, you can confirm whether a letter is at the start of a word; if both prev
and ch
are letters, then prev
must be capitalized and ch
not. The only tussle is how to read the previous character when the code first runs. Here’s my solution:
#include <stdio.h> #include <ctype.h> int main() { int ch,prev; /* must initialize prev */ prev = '\0'; /* filter loop */ while(1) { /* fetch input */ ch = getc(stdin); /* quit on EOF */ if( ch == EOF) break; /* process input */ if( isalpha(prev) ) ch = tolower(ch); if( isspace(prev) || prev=='\0' || prev=='(' ) ch = toupper(ch); /* send output */ putc(ch,stdout); /* save current as previous character */ prev = ch; } }
Variable prev
must be initialized before processing starts. Because no character is available at the beginning of input, prev
is set to the null character at Line 9.
In the endless while loop, input is fetched at Line 15 and the EOF
character tested at Line 17.
At Line 21, the value of character prev
is tested. When isalpha() is true, prev
holds a letter of the alphabet, upper or lower case. Therefore, the value of ch
should be lower case, and it’s converted at Line 22.
If the previous character is a space (tab, enter, space) or null, or a beginning parentheses, the value of ch
is set to uppercase at Line 24.
Line 27 sends character ch
to standard output. And line 29 assigns the value of prev
to the value of ch
and the loop continues.
I tried to conceive of other ways to process an initial caps filter, but it just can’t be done without storing at least one character of input. For example, it’s possible to read an entire line (or buffer) and process it on output. Still, the solution I devised seems simple enough.
With C programming, no two solutions need to be the same, nor is there any one solution that’s better than the others. If you coded a solution that properly processes input and translates the words output as initial caps, great!
I’ve been doing a lot of Python programming recently (yeah, really!) and it has a built-in capitalize function, obviously written in C.
I started looking into Python because it is widely used for machine learning, data science and that sort of thing, and I just wanted to see if there were any ideas I could “borrow” from Python to use elsewhere. However, I then started to get interested in the language in its own right.
What impressed me most is that it is very closely associated with C and the Python community are quite open about this, and the standard implementation is even called CPython. (Some other people might think of it as a “dirty secret” to be ashamed of: I think Java and C# people a guilty of this!)
I think the two languages complement each other very well – do the complex and intensive stuff in C for maximum performance, and the simpler infrastructure stuff in Python for rapid development.
I didn’t get round to implementing your exercise but I think I would have done something like capitalizing the first character and then iterating from 1 to the end, upper-casing anything after a space and lower-casing everything else.
I set out to learn Python earlier this year, before several other paying projects arrived. The book is still on my desk and I look forward to exploring the language further, especially for the reasons you give.