One of my older C programming books featured a sample program that translated English words into their Pig Latin equivalent. It’s time to revisit this code.
The program I wrote back in 2004, published in the C All-in-One Desktop Reference For Dummies (Wiley)(over 800 pages long!), is a filter. It’s a good, fun example for working a filter, but the code is long and I believe I could write it better 20 years later.
First, what is Pig Latin?
It’s English, but with the first part of the word flopped to the end. Either -ay or -hay is added, which makes it sound like Ecclesiastical Latin. (Think of a Roman Catholic priest speaking in an echoey church.) So, Hello becomes ello-Hay.
Second, the language has no rules. It’s a play on words — and an old one. Shakespeare’s play Love’s Labour’s Lost includes this snippet, called Dog Latin in the day: O, I smell false Latine; dunghill for unguem. Dog Latin evolved into Hog Latin and then to Pig Latin. I suppose the only “rule” is that it sounds like Latin. (Though it doesn’t, really.)
Third, to code it I’m writing a piglatin() function. The first step is to swallow the word and send it off to the function. I wrote the following skeleton to fetch a text from standard input, lop off the newline, then send the word (the text) to the piglatin() function and return it unmodified:
2024_12_14-Lesson-a.c
#include <stdio.h> /* translate a word into piglatin */ char *piglatin(char *s) { /* word starts with a vowel, add -hay */ /* move first consonant/consonant cluster add -ay */ return s; } int main() { char word[32]; char *s,*pl; printf("Original word: "); fgets(word,32,stdin); /* remove newline */ s = word; while(*s++) if( *s=='\n') *s='\0'; /* translate to pig latin */ pl = piglatin(word); printf("Translated word: %s\n",pl); return 0; }
The bulk of the main() function removes the newline automatically added by the fgets() function. The input text is then sent to the piglatin() function, which returns the word for output. Here’s a sample run:
Original word: hello
Translated word: hello
The code contains a comment in the piglatin() function that describes the pending operation: When the word starts with a vowel, affix the -hay
ending. Otherwise, move the first consonant or consonant cluster to the end of the word and add -ay
. Variations on these techniques differ. For example, some Pig Latin translations use yay instead of hay. Some omit the hyphens.
Rather than tackle the entire problem at once, my next update works only on those words that start with a vowel. To accomplish this task, I added a switch-case structure to the piglatin() function. For those words starting with a vowel, a new string is allocated with storage for the -hay
suffix. Then the new, Pig Latin word is built:
2024_12_14-Lesson-b.c
#include <stdio.h> #include <stdlib.h> #include <string.h> /* translate a word into piglatin */ char *piglatin(char *s) { char *pig; /* word starts with a vowel, add -hay */ switch(*s) { case 'a': case 'e': case 'i': case 'o': case 'u': pig = malloc( strlen(s)+4+1 ); /* "-hay" + '\0' */ if( pig==NULL ) return("Memory Error"); strcpy(pig,s); strcat(pig,"-hay"); break; /* move first consonant/consonant cluster add -ay */ default: pig = s; /* temp assignment */ } return pig; } int main() { char word[32]; char *s,*pl; printf("Original word: "); fgets(word,32,stdin); /* remove newline */ s = word; while(*s++) if( *s=='\n') *s='\0'; /* translate to pig latin */ pl = piglatin(word); printf("Translated word: %s\n",pl); return 0; }
In the piglatin() function, when the word starts with a vowel, pointer *pig
is allocated enough storage for the original word plus 4 for -hay
and one for the null character. The original string is copied to pig
, then -hay
is concatenated. The word is returned. For all other words, the original word is returned.
Here are some sample runs:
Original word: outside
Translated word: outside-hay
Original word: nothing
Translated word: nothing
In next week’s Lesson, I continue to build the Pig Latin translator by improving upon this code.