I am learning C, and wrote this pig-latin translator.
If no argument is given, it operates on standard input. Otherwise, it operates on the arguments given.
Here are some examples:
$ echo "The quick brown fox jumps over Vladmir's lazy young Yggdrasil!" | ./piglatin
Ethay ickquay ownbray oxfay umpsjay overway Admir'svlay azylay oungyay Yggdrasilway!
$ ./piglatin "Now is the time, for all good men to come to the aid of their party"
Ownay isway ethay imetay, orfay allway oodgay enmay otay omecay otay ethay aidway ofway eirthay artypay
#include <err.h>
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define SUFFIXC "ay"
#define SUFFIXV "way"
static void usage(void);
static void piglatin(const char *s);
static int isvowel(const char *s);
/* Encodes English-language phrases into Pig Latin. */
int
main(int argc, char *argv[])
{
int c;
while ((c = getopt(argc, argv, "h")) != -1) {
switch (c) {
case 'h':
default:
usage();
break;
}
}
argc -= optind;
argv += optind;
if (argc == 0) {
char *line = NULL;
size_t linesize = 0;
ssize_t linelen;
while ((linelen = getline(&line, &linesize, stdin)) != -1) {
if (line[linelen - 1] == '\n')
line[linelen - 1] = '\0';
piglatin(line);
}
free(line);
if (ferror(stdin))
err(EXIT_FAILURE, "stdin");
} else {
while (argc-- > 0)
piglatin(*argv++);
}
if (ferror(stdout))
err(EXIT_FAILURE, "stdout");
return EXIT_SUCCESS;
}
/* translate s into Pig Latin */
static void
piglatin(const char *s)
{
const char *p, *onset, *root, *end, *suffix;
bool upper;
while (*s != '\0') {
while (!isalpha(*s) && *s != '\'' && *s != '\0')
putchar(*s++);
upper = false;
if (isupper(*s))
upper = true;
if (*s == '\0')
break;
onset = s;
while (isalpha(*s) && !isvowel(s)) {
if (*s == 'q' && *(s+1) == 'u')
s++;
s++;
}
root = s;
while (isalpha(*s) || *s == '\'')
s++;
end = s;
suffix = (onset == root) ? SUFFIXV : SUFFIXC;
for (p = root; p != end; p++) {
if (p == root && upper)
putchar(toupper(*p));
else
putchar(*p);
}
for (p = onset; p != root; p++) {
if (p == onset && upper)
putchar(tolower(*p));
else
putchar(*p);
}
printf("%s", suffix);
}
printf("\n");
}
/* test if first letter of s is a vowel */
static int
isvowel(const char *s)
{
switch (tolower(*s)) {
case 'a': case 'e': case 'i': case 'o': case 'u':
return 1;
case 'y':
return (isvowel(s+1) ? 0 : 1);
}
return 0;
}
static void
usage(void)
{
(void) fprintf(stderr, "usage: piglatin [phrase...]\n");
exit(EXIT_FAILURE);
}