The Pig Latin Translator, Part III

The final step in my Pig Latin journey is to process an entire English language sentence. The piglatin() function, finished in last week’s Lesson, requires no updates. But chopping a sentence into words and sending them off to be processed individually proved to be an interesting exercise.

To parse words from a sentence, I process the input string from beginning to end. A while loop churns through each character. To find words in the sentence, an if test uses the isalapha() ctype function to check for letters of the alphabet, upper- or lowercase:

while(start-sentence<len)
{
    if( isalpha(*start) )

Pointer variable start is initialized to the input string’s address, sentence; len is the string’s length.

When the isalpha() test is true, pointer start references the start of a word. Pointer end is assigned the address stored in start. Then a nested while loop continues processing alphabetic characters to locate the end of the word, moving pointer end along the way:

end = start;
while( isalpha(*end) || *end=='\'' )
    end++;

The loop ends when a word is found. The non-alpha character after the word is saved in char variable save, then the word referenced by pointer start is capped:

save = *end;
*end = '\0';

The word is now parsed and can be processed by the piglatin() function:

printf("%s",piglatin(start));

After the Pig Latin translation is output, variable start is updated to look for another word. The non-alpha character saved in variable save is output to ensure consistency between the original and Pig Latin string:

start = end+1;
putchar(save);

Here is the full code:

2024_12_28-Lesson.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

/* test for vowels */
int isvowel(char a)
{
    if( a=='A' || a=='a' )
        return 1;
    if( a=='E' || a=='e' )
        return 1;
    if( a=='I' || a=='i' )
        return 1;
    if( a=='O' || a=='o' )
        return 1;
    if( a=='U' || a=='u' )
        return 1;
    return 0;
}

/* translate a word into piglatin */
char *piglatin(char *s)
{
    char *si,*pig;

    /* word starts with a vowel, add -hay */
    if( isvowel(*s) )
    {
        pig = malloc( strlen(s)+4+1 );    /* "-hay" + '\0' */
        if( pig==NULL )
            return("Memory Error");
        strcpy(pig,s);
        strcat(pig,"-hay");
    }
    else
    {
    /* move first consonant/consonant cluster
       add -ay */
        si = s;
        while( !isvowel(*si) )
        {
            si++;
            if( *si=='\0' )
                return("Invalid word");
        }
        pig = malloc( strlen(s)+3+1 );    /* "-ay" + '\0' */
        if( pig==NULL )
        return("Memory Error");
        strcpy(pig,si);
        strcpy(pig,"-");
        strncat(pig,s,si-s);
        strcat(pig,"ay");
    }

    return pig;
}

int main()
{
    char sentence[BUFSIZ];
    char *start,*end;
    char save;
    int len;

    printf("Original sentence: ");
    fgets(sentence,BUFSIZ,stdin);
    printf("Piglatin sentence: ");

    /* chop sentence into word chunks */
    start = sentence;
    len = strlen(sentence);
    while(start-sentence<len)
    {
        if( isalpha(*start) )
        {
            end = start;
            while( isalpha(*end) || *end=='\'' )
                end++;
            save = *end;
            *end = '\0';
            printf("%s",piglatin(start));
            start = end+1;
            putchar(save);
        }
        else
        {
            putchar(*start);
            start++;
        }
    }

    return 0;
}

The isvowel() and piglatin() functions are unchanged from last week’s code. The only modifications are in the main() function, as described earlier. Here is a sample run:

Original sentence: Greetings from Dan Gookin!
Piglatin sentence: eetings-Gray om-fray an-Day ookin-Gay!

I suppose another modification I could make would be to transform this code into a filter, as presented in my book C All-In-One Desk Reference For Dummies. But I’m weary of the whole Pig Latin thing, so I’ll save this task for a future Lesson.

Leave a Reply