Primitive solution of squeeze
The code is relatively neat and appears to work properly, so you seem to be well on your way to mastering C.  Here are some things that may help you on that road.

Strings are automatically terminated

The code currently includes these two lines:

char s1[] = "I am a test.\0";
const char *s2 = "AE\0";


However, the explicit '\0' at the end of these strings is not necessary.  A C string is automatically terminated with an implicit '\0' character, so these lines would normally be written as:

char s1[] = "I am a test.";
const char *s2 = "AE";


Move function bodies to avoid declaration

Modern C no longer requires function declarations before every function definition.  As long as, reading from top to bottom, each function definition does not refer to anything not yet defined, the function declarations may be omitted.  So in this program, if you put the function definitions in the order toUpper, contains, squeeze and main, you can omit the declarations.  This is handy because it means you only need to maintain the function signature in one place rather than two.

Use bool instead of int where appropriate

The contains function returns 1 if the value is found or 0 otherwise.  That is, it's essentially returning a boolean value.  You can make that more clear by using #include &lt;stdbool.h&gt; and writing the function as:

bool contains(char toCheck, const char *toRemove) { /* ... */ }


Then the return statements can be return true; and return false;  As documented here, bool has been standard C since 1999.

Use standard functions

I know this is a learning exercise and you're just starting, but it's generally encouraged to use standard functions rather than duplicating them.  For instance, toupper has been part of the standard since 1989.

Avoid creating unneeded variables

The variable c in the contains() routine is not really needed.  Instead of this:

if ((c = toUpper(toCheck)) == toRemove[index]){


You can write this:

if (toUpper(toCheck) == toRemove[index]){