Improving and optimizing squeeze() function
You want to avoid repeat iteration over the 2nd string, which is O(N).  Do this N times and you have an O(N2) algorithm.

One trick you could use is to build a lookup table of the chars in str2.  This would cost O(N) and some extra memory upfront, but then subsequent lookups in the table could be brought down to O(1).

Here's a simple example.  The trade-off is this takes a bit more memory and makes some assumptions about the range of char.  It also clobbers the buffer of str1:

#include &lt;limits.h&gt;   // for UCHAR_MAX

char *squeeze (char *str1, char *str2)
{
   char present[UCHAR_MAX + 1] = {0};
   char *src, *dst;

   // Build lookup table of chars in str2
   //
   while (*str2)
      present[(unsigned char)*str2++] = 1;

   // Iterate through str1, removing chars along the way.
   //
   src = dst = str1;
   while (*src)
   {
      // Is *src in str2?
      //
      if (present[(unsigned char)*src])
      {
         // Yes, remove this char.. (Advance src but not dst.)
         //
         ++src;
      }
      else
         *dst++ = *src++;
   }

   // NUL terminator
   //
   *dst = 0;

   return str1;
}