Deadbeef : finding all words made of hexadecimal digits Hexadecimal 0xdead, 0xbeef are the magic numbers because they're also English words. 
I decided to find such words as many as possible. How to do it? We need large English text let's say Ulysses by James Joyce and a program which extracts all words consists of hexadecimal digits. For simplicity, I decided to drop leet-language support. It dramatically shrinks the range but keeps real words only. 

The code below extract magic numbers from given text and prints them to stdout in lower case 

#include &lt;ctype.h&gt;
#include &lt;stdio.h&gt;

#define MAX_LEN 256

int process_file(FILE* file);

int main(int argc, char* argv[]) {

  if (argc == 1) {
    process_file(stdin);
  } else {
    size_t i = 0;
    char* filename;
    FILE* file;
    int err;
    while ((filename = argv[++i]) != NULL) {
      file = fopen(filename, "r");
      if (!file) {
        perror("fopen() failed");
        return 1;
      }
      err = process_file(file);
      fclose(file);
      if (err) {
        return 2;
      }
    }
  }

  return 0;
}

int process_file(FILE* file) {
  char word[MAX_LEN];
  size_t p = 0;
  int c;
  while (1) {
    c = getc(file);
    if (isspace(c) || c == EOF) {
      /* end of word or end of emptiness */

      if (p &gt; 0 &amp;&amp; p &lt; MAX_LEN &amp;&amp; p % 2 == 0) {
        word[p] = 0;
        printf("%s\n", word);
      }

      if (c == EOF) {
        break;
      }

      p = 0;
      continue;
    }

    if (p &gt; MAX_LEN - 1) {
      continue;
    }

    if ((c &gt;= 'A' &amp;&amp; c &lt;= 'F') || (c &gt;= 'a' &amp;&amp; c &lt;= 'f')) { /* abcdef ABCDEF */
      word[p++] = tolower(c);
    } else {
      /* skip this word */
      p = MAX_LEN;
    }
  }

  if (feof(file)) {
    return 0;
  }

  if (ferror(file)) {
    perror("i/o error occurred");
  }

  return 1;
}


Commands 

echo "Dead of being fed with beef for a decade" | ./deadbeaf | sort | uniq


should give

beef
dead
decade
It is customary to put helper functions first and main() last, to avoid having to write forward declarations like int process_file(FILE* file);.

process_file() is a very generic name.  I suggest renaming it to print_hex_words().

The process_file() function returns an error code.  Therefore, the responsibility for printing any error message for I/O errors should lie with main().

You assume that words are delimited by whitespace, and have neglected to deal with punctuation.

Your algorithm is very tedious.  Instead of using getc() to read a byte at a time, use fscanf() to read a whitespace-delimited word at a time.  To skip to the end of a sequence consisting solely of A-F characters, use strspn(…, "ABCDEFabcdef").

#define xstr(s) str(s)
#define str(s) #s

int print_hex_words(FILE* file) {
    char word_buf[MAX_LEN + 1];
    while (1 == fscanf(file, "%" xstr(MAX_LEN) "s", word_buf)) {
        char *word, *end, *trail_punct;

        /* Skip leading punctuation */
        for (word = word_buf; ispunct(*word); word++);

        end = word + strspn(word, "ABCDEFabcdef");

        /* Skip trailing punctuation */
        for (trail_punct = end; ispunct(*trail_punct); trail_punct++);

        if (word != end &amp;&amp; *trail_punct == '\0') {
            /* NUL-terminate the word and convert it to lowercase */
            *end = '\0';
            for (end = word; (*end = tolower(*end)); end++);

            printf("%s\n", word);
        }
    }
    return ferror(file);
}


Instead of … | sort | uniq, you can use … | sort -u.