Uppercase-lowercase Combinator


This program will take an input such as:

dog54
And it will give the following output:
dog54
Dog54
dOg54
DOg54
doG54
DoG54
dOG54
DOG54
The program reads words from "standard input" and prints the combinations to "standard output". Here's how to give it one word:
echo dog | ./updown
And here's how to give it a dictionary file:
cat my_dictionary.txt | ./updown
If you want the output to go to a file, then do:
cat my_dictionary.txt | ./updown > my_even_better_dictionary.txt
Here's the source code for it:
#include <stdint.h>
#include <ctype.h>    /* tolower, toupper, isalpha */
#include <stdio.h>    /* puts */
#include <string.h>   /* strlen */

void PrintCombos(char *const str)
{
    uint_fast8_t const len = strlen(str);

    uint_fast8_t amount_letters;

    uint_fast64_t cases, letters;

    /* For example:

                "tEsT74kT"
         cases = 01010001  (the 1's mean uppercase letters)
       letters = 11110011  (the 1's mean letters)
    */

    uint_fast64_t mask;
    uint_fast8_t char_index;

    for (letters = 0, amount_letters = 0, mask = 1, char_index = 0;
                                                 len != char_index;
                                           mask <<= 1, ++char_index)
    {
        if (isalpha(str[char_index]))
        {
            ++amount_letters;
            letters |= mask;
        }
    }

    uint_fast64_t const one_past_max_count = (uint_fast64_t)1 << amount_letters;

    for (cases = 0; one_past_max_count != cases; ++cases)
    {
        uint_fast64_t mask_letters;

        for (mask = 1, mask_letters = 1, char_index = 0;
                             one_past_max_count != mask;
           mask <<= 1, mask_letters <<= 1, ++char_index)
        {
            while ( !(letters & mask_letters) )
            {
                mask_letters <<= 1;
                ++char_index;
                if (char_index >= len) return;
            }

            if (cases & mask) str[char_index] = toupper((char unsigned)str[char_index]);
                         else str[char_index] = tolower((char unsigned)str[char_index]);
        }

        puts(str);
    }
}

int main(void)
{
    char line[65]; /* 63 for line from file,
                      1 for new line character,
                      1 for null terminator
                   */

    while ( fgets(line,sizeof line,stdin) )
    {
        uint_fast8_t const index_of_final_char = strlen(line) - 1;

        if (line[index_of_final_char] == '\n')
        {
            line[index_of_final_char] = '\0';
        }

        PrintCombos(line);
    }

    return 0;
}
You can compile it as follows:
gcc updown.c -D NDEBUG -s -O3 -o updown


Virjacode Home