No more filthy words
Look here:


for (int i = 0; i &lt; strlen(input); i++) {



Note that strlen(input) is O(n), proportional to the length of the input.  That makes your algorithm O(n2), which is slower than it should be.  If you need to call strlen(), make sure to call it just once.  However, this problem is easily solvable without using strlen() at all.



Others have pointed out your memory leak.  What should be done about it?  The output is never longer than the input, right?  Therefore, I would say that your best option is to overwrite the input with the sanitized output.  There is no need to allocate any additional memory, and no need to worry about the buffer size.  (If the caller wants to keep the original string, then the caller can duplicate it first.)

There is no need to write a to_lowercase() function that calls tolower() on each character in the string.  Just call tolower() as part of the loop.

The character_value comparisons could be simplified to isalpha(character_value).  Your naming style is inconsistent between character_value and wordMatched.  I would change int character_value to char c.



With this code…


} else if (wordMatched) {
    wordMatched = false;
    sanitized[iterator++] = ' ';
}



… you output a space when transitioning from a letter to a non-letter.  However, that would output a space corresponding to the 7 at the end of 13What213are;11you-123+138doing7.  In my opinion, it would be better if it didn't output a space at the end.

Suggested solution

I've put some miscellaneous remarks in comments.

#include &lt;assert.h&gt;
#include &lt;ctype.h&gt;
#include &lt;stdbool.h&gt;
#include &lt;stdio.h&gt;              // You missed this for printf(3)
#include &lt;stdlib.h&gt;

/**
 * Replaces consecutive non-alphabetic characters in the input
 * string with a single space.  Non-alphabetic characters at the
 * beginning and end are trimmed off as well.  The remaining ASCII
 * letters are replaced with their lowercase counterparts.
 *
 * The input string will be overwritten.
 *
 * Returns the length of the sanitized output.
 */
size_t sanitize(char *s) {
    bool needSpace = false;
    char *out = s;
    for (char *in = s; *in != '\0'; in++) {
        assert(out &lt;= in);
        if (isalpha(*in)) {
            if (needSpace) *out++ = ' ';
            needSpace = false;
            *out++ = tolower(*in);
        } else if (out &gt; s) {
            needSpace = true;
        }
    }
    *out = '\0';
    return out - s;
}

int main(int argc, const char *argv[]) {
    char line[1024];
    FILE *file = stdin;        // Read from stdin if no filename given
    if (argc &gt; 1 &amp;&amp; !(file = fopen(argv[1], "r"))) {
        perror(argv[1]);       // Some error handling that you didn't have
        return EXIT_FAILURE;
    }
    while (fgets(line, sizeof(line), file)) {
        sanitize(line);
        puts(line);            // Don't need printf() when puts() will do
    }
}