Task: Alternade words

C: #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>

#define WORD_BUF_SIZE 30
#define MIN_WORD_SIZE 6


void fail(void) {
    fprintf(stderr, "%s\n", strerror(errno));
    exit(42);
}


struct trie_node {
    char ch, final;
    struct trie_node *parent, *sibling, *root, *child; 
};

struct trie_node *alloc_node() {
    struct trie_node *t = calloc(1, sizeof(struct trie_node));
    if (t == NULL) fail();
    return t;
}

struct trie_node *make_sibling(struct trie_node *node) {
    struct trie_node *t = alloc_node();
    node->sibling = t;
    t->ch = node->ch;
    t->parent = node->parent;
    t->root = node->root;
    return t;
}

struct trie_node *make_child(struct trie_node *node, char ch) {
    struct trie_node *t = alloc_node();
    t->parent = node;
    t->ch = ch;
    t->root = node->root;
    node->child = t;
    return t;
}


struct trie_node *add_word(struct trie_node *root, const char *word) {
    struct trie_node *cur = root;
    for (; *word; word++) {
        while (cur->child == NULL || cur->child->ch != *word) {
            if (cur->child == NULL) {
                
                make_child(cur, *word);
            } else {
                
                if (cur->sibling == NULL) make_sibling(cur);
                cur = cur->sibling;
            }
        }
        
        
        cur = cur->child;
    }
    cur->final = 1; 
    return cur;
}


struct trie_node *find_word(struct trie_node *root, const char *word) {
    struct trie_node *cur = root;
    for (; *word && cur; word++) {
        while (cur != NULL && cur->child != NULL && cur->child->ch != *word) {
            cur = cur->sibling;
        }
        if (cur == NULL) return NULL; 
        cur = cur->child;
    }
    if (cur && cur->final) return cur;
    else return NULL;
}


void scan_trie(struct trie_node *node, void callback(struct trie_node *)) {
    if (node == NULL) return;
    if (node->final) callback(node);
    scan_trie(node->child, callback);
    scan_trie(node->sibling, callback);
}


char *get_word(struct trie_node *node, char *buffer) {
    char t, *ch = buffer, *s = buffer;
    for (; node != NULL; node=node->parent) *ch++ = node->ch;
    for (ch-=2; ch >= s; ch--, s++) *ch ^= *s ^= *ch ^= *s;
    return buffer;
}


void check_alternade(struct trie_node *node) {
    static char word[WORD_BUF_SIZE], even[WORD_BUF_SIZE], odd[WORD_BUF_SIZE];
    char *p_even = even, *p_odd = odd;
    int i;
    
    
    if (strlen(get_word(node, word)) < MIN_WORD_SIZE) return;
    
    
    for (i=0; word[i]; i++) {
        if (i & 1) *p_odd++ = word[i];
        else *p_even++ = word[i];
    }
    *p_odd = *p_even = '\0';
        
    
    if (find_word(node->root, even) && find_word(node->root, odd)) {
        printf("%-20s%-10s%-10s\n", word, even, odd);
    }
}
          
int main(void) {
    struct trie_node *root = alloc_node();
    root->root = root;
    char word[WORD_BUF_SIZE], *nl;
    
    
    while (!feof(stdin)) {
        fgets(word, WORD_BUF_SIZE, stdin);
        if (nl = strchr(word, '\n')) *nl = '\0';  
        add_word(root, word);
    }
    
    
    scan_trie(root, check_alternade);
    return 0;
}


C++: #include <cstdlib>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <set>
#include <string>

int main(int argc, char** argv) {
    const char* filename(argc < 2 ? "unixdict.txt" : argv[1]);
    std::ifstream in(filename);
    if (!in) {
        std::cerr << "Cannot open file '" << filename << "'.\n";
        return EXIT_FAILURE;
    }
    std::string line;
    std::set<std::string> dictionary;
    while (getline(in, line))
        dictionary.insert(line);
    std::cout << std::left;
    for (const std::string& word : dictionary) {
        size_t len = word.size();
        if (len < 6)
            continue;
        std::string word1, word2;
        for (size_t i = 0; i < len; i += 2) {
            word1 += word[i];
            if (i + 1 < len)
                word2 += word[i + 1];
        }
        if (dictionary.find(word1) != dictionary.end()
            && dictionary.find(word2) != dictionary.end()) {
            std::cout << std::setw(10) << word
                    << std::setw(6) << word1 << word2 << '\n';
        }
    }
    return EXIT_SUCCESS;
}