Highlight a Chunk of Text – Solution

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!

Leave a Reply