Your task for this month’s Exercise is to code a text-processing routine that interprets the ^ character as a toggle for all-caps output. This challenge can be difficult, depending on how you interpret the toggle.
For my first solution, I used an if-else decision structure. One part processed uppercase text and the other processed normal text based on when the ^ character is encountered. This solution didn’t work, especially when two ^ characters were encountered in a row. To handle that case, more complexity and ugliness was required. So, I started over.
For my second attempt, I decided to make the ^ character activate a toggle. When the ^ character is encountered, the value of the uc
variable is set to 1. When the ^ character appears again, uc
is reset to 0:
uc = uc ? 0 : 1;
Variable uc
is initialized to 0. (I used an int variable instead of a _Bool, though a _Bool would also work.) The above ternary function toggles the value of uc
between 0 and 1: If it’s already 0, uc
is set to 1, otherwise the value is reset to 0.
As the code processes the text, a second ternary function converts characters to uppercase based on the value of uc
:
*o = uc ? toupper(*i) : *i;
Pointer variable o
references the output string, pointer variable i
references the input string. When the value of uc
is 1 (TRUE), the toupper() function converts the input character to upper case. Otherwise, the input character slides through unaffected.
I could have used an if-else structure in both instances instead of the ternary function, which is more readable. I could have also used array notation to work with the input and output strings, but I didn’t because understanding pointers is important.
Here is the full code for my solution:
#include <stdio.h> #include <ctype.h> #define SIZE 255 int main() { char input[SIZE]; char output[SIZE]; char *i,*o; int uc; /* Initialize variables */ i = input; o = output; uc = 0; /* use fgets() to read and restrict input */ printf("Input: "); fgets(input,SIZE,stdin); /* process the line */ while( *i!='\n') { if( *i =='^') { uc = uc ? 0 : 1; /* toggle on/off */ i++; /* skip ^ char */ } else { *o = uc ? toupper(*i) : *i; o++; i++; } if( *i=='\0') break; } /* display result */ printf("Output: %s\n",output); return(0); }
The while loop at Line 23 processes the string until the newline is encountered. Remember that the fgets() function retains the newline.
The i++
statement at Line 28 increments the input string beyond the ^ character. And in the else statements, both o
and i
are incremented to continue working through the strings. The size of the o
buffer can be the same as the i
buffer as it can’t be larger due to skipping the ^ character in the o
string.
The if test at Line 36 checks for the null character, \0
. This test is necessary should the input string length be greater than the buffer size. When that happens, the input string terminates with a null character, not a newline.
My solution is only one approach. If yours processes the strings as shown in the examples, great!