You MUST add a NUL terminator to mark the end of a C string.
Adding a NUL terminator character isn't automatic (unless documentation states that a function call writes the NUL terminator character for you).
In your case, use:
s[20] = 0;
As mentioned in the comments, C strings are defined by the terminator NUL character. The NUL character is required also by all the strXXX
C functions.
If you don't mark the end of the string with a NUL, you have a (binary) sequence of characters, but not a C string. These are sometimes referred to as binary strings and they cannot use the strXXX
library functions.
Why do you get Correct Results
It is likely that you get correct results mostly by chance.
The most probable explanation for the correct results is that the OS you are using provides you with a "clean" memory stack (the initial stack memory is all zero)... this isn't always the case.
Since you never wrote on the stack memory prior to executing your code, the following byte is whatever was there before (on your OS, that byte was set to zero when the stack was first initialized).
However, this will not be true if the OS does not provide you with a "clean" stack or if your code runs on a previously used stack.